Django ValueError:无法查询“用户”:必须是“配置文件”实例

问题描述

我正在尝试向Django中的博客应用添加简单的用户用户消息传递功能我有一个允许用户发送消息的视图,但是我在以后显示消息时遇到了困难。这是我的消息模型:

class Message(models.Model):
    user = models.ForeignKey(Profile,on_delete=models.CASCADE,related_name='messages')
    sender = models.ForeignKey(Profile,related_name='messages_from')
    message = models.TextField(blank=True)
    timestamp = models.DateTimeField(default=timezone.Now,editable=False)
    unread = models.BooleanField(default=True) 

以及相关的个人资料模型:

class Profile(models.Model):
    first_name = models.CharField(max_length=100,blank=True)
    last_name = models.CharField(max_length=100,blank=True)
    user = models.OnetoOneField(User,on_delete=models.CASCADE)
    slug = models.SlugField(unique=True,blank=True)
    updated = models.DateTimeField(auto_Now=True)
    created = models.DateTimeField(auto_Now_add=True)

这是我的MessagesView尝试:

class MessagesView(ListView):
    model = Profile
    template_name = 'users/messages.html'
    context_object_name = 'msg'

    def get_queryset(self):
        return Profile.objects.filter(messages_from__isnull=False,messages__user_id=self.request.user)

这是网址:

path('messages/<int:pk>/',MessagesView.as_view(),name='messages'),

尝试加载此页面时,我收到错误Cannot query "user": Must be "Profile" instance,其中“用户”是我要加载的消息的登录用户名称。我花了很长时间来寻找解决方案,但没有发现与我的案子有关的任何事情。请帮忙

解决方法

您的Message的{​​{1}}字段是user,而不是ForeignKey(因此最好将字段重命名为{{1 }}。因此,这意味着像Profile这样的过滤没有太大意义。

您可以通过以下方式过滤从Userprofile的关系:

messages__user_id=self.request.user

在这里.distinct() [Django-doc]是必要的,以防止多次检索相同的Profile

由于这是User,因此您可能还应该返回class MessagesView(ListView): model = Profile template_name = 'users/messages.html' context_object_name = 'msg' def get_queryset(self): return Profile.objects.filter( messages_from__isnull=False,messages__user__user=self.request.user ).distinct(),将Profile设置为MessagesView的事实也暗示了这一点。因此,在这种情况下,您应该返回Message中的context_object_name,而不是msg s:

QuerySet

如果将Message重命名为Profile,请使用class MessagesView(ListView): model = Message template_name = 'users/messages.html' context_object_name = 'msg' def get_queryset(self): return Message.objects.filter( user__user=self.request.user )进行过滤。


注意:您可以将视图限制为基于类的视图,以使用 LoginRequiredMixin mixin [Django-doc]


注意:与直接使用settings.AUTH_USER_MODEL [Django-doc]相比,通常最好使用User model [Django-doc]来引用用户模型。有关更多信息,请参见referencing the User model section of the documentation