Django ValueError: Cannot query "user": Must be "Profile" instance

Django ValueError: Cannot query "user": Must be "Profile" instance

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

class Message(models.Model):
    user = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='messages')
    sender = models.ForeignKey(Profile, on_delete=models.CASCADE, 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)

这里是 url:

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

尝试加载此页面时,我收到错误 Cannot query "user": Must be "Profile" instance,其中“用户”是我尝试加载消息的已登录用户的名称。我花了很长时间在谷歌上搜索解决方案,但没有发现与我的案例相关的任何内容。请帮忙

您的 Message 具有 user 字段 ForeignKeyProfile,而不是 User(因此最好将字段重命名为 profile).因此,这意味着像 messages__user_id=self.request.user 这样的过滤没有多大意义。

您可以按照从 ProfileUser 的关系进行过滤:

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,
            <b>messages__user__user=self.request.user</b>
    ).distinct()

此处需要 .distinct() [Django-doc] 以防止多次检索相同的 Profile

因为这是一个 MessagesView,你还可能应该 return Messages,你将 context_object_name 设置为 msg 的事实也暗示到那个。在那种情况下,你应该 return QuerySet of Messages,而不是 Profiles:

class MessagesView(ListView):
    model = <b>Message</b>
    template_name = 'users/messages.html'
    context_object_name = 'msg'

    def get_queryset(self):
        return <b>Message</b>.objects.filter(
            <b>user__user=self.request.user</b>
        )

如果您将 ForeignKey 重命名为 profile,您可以使用 profile__user=self.request.user 进行过滤。


Note: You can limit views to a class-based view to authenticated users with the LoginRequiredMixin mixin [Django-doc].


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.