【问题标题】:Django query for a related objectDjango 查询相关对象
【发布时间】:2020-07-16 11:10:49
【问题描述】:

我有两个模型 Post 和 UserBookmarks。

Project/App1 的models.py

from App2 import UserBookmarks

class Post(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
        author = models.ForeignKey(User, on_delete=models.CASCADE)
        title = models.CharField(verbose_name="Title", max_length=20)
        content = models.TextField(verbose_name="Post Content", max_length=2000)
        ...
        bookmarks = GenericRelation(UserBookmarks, related_query_name='post')

Project/App2 的models.py

bookmarkable_models = models.Q(app_label='App', model='post') | models.Q(app_label='App', model='model-b') | models.Q(app_label='App', model='model-c')

class UserBookmarks(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
    content_type = models.ForeignKey(ContentType, limit_choices_to=bookmarkable_models, on_delete=models.CASCADE, null=True, blank=False)
    object_id = models.CharField(max_length=50, blank=False)
    content_object = GenericForeignKey('content_type', 'object_id')
    date_added = models.DateTimeField(auto_now_add=True, blank=False)

现在我想检查用户是否已将帖子作为我的 views.py 添加到他的书签中,但我不明白我的查询必须是什么样子。目前我正在做这样的事情:

def post_add_bookmark(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == 'GET':
        if post.bookmarks.filter(user=request.user).exists():
            messages.error(request,
                           'You already added this Post to your Bookmarks')
            return redirect('post_detail', pk=post.pk)
        else:
            post.bookmarks.create(user=request.user, object_id=post.pk)
            messages.success(request, 'Post has been added to your Bookmarks')
            return redirect('post_detail', pk=post.pk)
    else:
        messages.error(request, 'Something went wrong')
        return redirect('post_detail', pk=post.pk)

可以。向我解释这个查询必须是什么样子才能检查它是否已经存在。 目前我收到以下错误:

无法查询“peter123”:必须是“UserBookmarks”实例。

【问题讨论】:

    标签: django querying reverse-lookup


    【解决方案1】:

    您可以检查post 是否已被用户添加为书签:

    post<b>.bookmarks</b>.filter(<b>user=request.user</b>).exists()

    但是,在数据库级别强制执行此操作可能是一个好主意,这样根本不可能为同一用户存储相同的书签:

    class UserBookmarks(models.Model):
        # …
    
        class Meta:
            constraints = [
                models.UniqueConstraint(fields=['user, content_type', 'object_id'], name='unique_bookmark')
            ]

    或在之前:

    class UserBookmarks(models.Model):
        # …
    
        class Meta:
            unique_together = [['user, content_type', 'object_id']]

    【讨论】:

    • 我相应地更新了我的问题views.py。使用您的解决方案,我似乎可以将相同的帖子添加 x 次作为书签。似乎由于某种原因没有检查整个 if 语句
    • 即使您更新的答案我遇到了问题:App2.UserBookmarks: (models.E012) 'unique_together' 指的是不存在的字段 'user, content_type'。因此,我将您的语法更改为: unique_together = ('user', 'content_type', 'object_id') 也再次遇到以下执行:App2_userbookmarks` (errno: 150 "Foreign key constraint is wrongly forms")')跨度>
    • unique_together = [['user', 'content_type', 'object_id']] 让迁移工作但仍然没有效果
    • @MarkusBrede:那么您很可能使用另一个userobject_idcontent_typeunique_together 毕竟是在 database 端强制执行的。如果您尝试使用相同的userobject_idcontent_type 创建第二条记录,它将引发INTEGRITY ERROR。所以在我看来,您的视图适用于不同的用户、发布主键等。
    • 作为 user == request.user 我不明白这一点,所以我应该只能访问请求用户。我将尝试从头开始构建我的功能。
    猜你喜欢
    • 2018-10-14
    • 2015-03-07
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 2018-09-13
    • 2016-07-11
    • 1970-01-01
    相关资源
    最近更新 更多