我正在尝试编写一个用户可以提交照片的应用程序。部分原因是投票支持照片。所以在我的models.py中我有:
photos/models.py
class Photo(models.Model):
votes = models.IntegerField(default=0)
users_voted = models.ManyToManyField(User, related_name='voters', blank=True, null=True)
users_voted ManyToManyField确保人们不能投票两次。这一切都很好,但目前我正在开发MPTT评论的项目中的另一个应用程序。我希望用户也可以对彼此的评论进行投票。所以我将投票代码复制到我的评论模型中:
comments/models.py
class MyMPTTComment(MPTTModel, Comment):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
cvotes = models.IntegerField(default=0)
users_voted = models.ManyToManyField(User, related_name='cvoters')
这会按预期在数据库中创建一个表。但是当我尝试使用我的view.py代码访问它时,我得到了FieldError:
def comment_vote(request):
if request.GET.has_key('id'):
try:
id = request.GET['id']
target = MyMPTTComment.objects.get(id=id)
user_voted = target.users_voted.filter(
username=request.user.username
)
我已经在这一段时间里摸不着头脑了。其他有类似问题的人发现它可能与Django加载模块的时间(http://chase-seibert.github.io/blog/2010/04/30/django-manytomany-error-cannot-resolve-keyword-xxx-into-a-field.html)有关,但摆弄模块命令试图影响它们的加载时间什么也没做。
错误说Choices are: ... voters
,为什么cvoters
无法解决?
编辑:添加完整错误和追溯:
Internal Server Error: /commentvote/
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py", line 25, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/root/photoproject/photos/views.py", line 300, in comment_vote
username=request.user.username
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 155, in filter
return self.get_query_set().filter(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 615, in get_query_set
return super(ManyRelatedManager, self).get_query_set().using(db)._next_is_sticky().filter(**self.core_filters)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 669, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 687, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1271, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1139, in add_filter
process_extras=process_extras)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1337, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'cvoters' into field. Choices are: comment_comments, comment_flags, date_joined, email, first_name, friend_set, groups, id, invitation, is_active, is_staff, is_superuser, last_login, last_name, logentry, moderated_messages, password, photos, received_messages, registrationprofile, sent_messages, to_friend_set, user_permissions, userbio, username, voters
Django v1.5.4
发布数据库架构:
CREATE TABLE "comments_mympttcomment" ("rght" integer unsigned NOT NULL, "parent_id" integer, "level" integer unsigned NOT NULL, "lft" integer unsigned NOT NULL, "tree_id" integer unsigned NOT NULL, "cvotes" integer NOT NULL, "comment_ptr_id" integer PRIMARY KEY);
CREATE TABLE "comments_mympttcomment_users_voted" ("id" integer NOT NULL PRIMARY KEY, "mympttcomment_id" integer NOT NULL, "user_id" integer NOT NULL);
CREATE TABLE "photos_photo" (
"id" integer NOT NULL PRIMARY KEY,
...
"votes" integer NOT NULL,
"user_id" integer REFERENCES "auth_user" ("id"),
);
CREATE TABLE "photos_photo_users_voted" (
"id" integer NOT NULL PRIMARY KEY,
"photo_id" integer NOT NULL,
"user_id" integer NOT NULL REFERENCES "auth_user" ("id"),
UNIQUE ("photo_id", "user_id")
);
注意到comments-user表不包含“REFERENCES”auth_user“(”id“)”,但我不知道为什么。如上所述,注释模型包含与photos表完全相同的ManytoManyField,从django.contrib.auth.models导入用户进行导入。
答案 0 :(得分:0)
我认为问题是由MyMPTTComment
中使用多重继承引起的。从模型的定义中删除Comment
:
class MyMPTTComment(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
cvotes = models.IntegerField(default=0)
users_voted = models.ManyToManyField(User, related_name='cvoters')
您可以再次添加父字段。我找到了与您想要做的事情类似的实现here。
答案 1 :(得分:0)
您尝试过滤查询集管理器而不是字段。当你说:
users_voted = models.ManyToManyField(User, related_name='cvoters')
您要求Django向User实例添加名为cvoters
的管理器,而不是User模型的新字段。
我引用Document how related_name affects QuerySet filtering。
因此,由于cvoters不是字段,因此您无法对其进行过滤。而是过滤您感兴趣的实际字段。