首页 > 解决方案 > 从 Django ORM 中提取外连接

问题描述

我的项目中有以下两个模型。

class Blog(models.Model):   
    title=models.CharField(max_length=20, blank=False, default='')
    content=models.CharField(max_length=2000, blank=False, default='')

class UserLikedBlogs(models.Model):
    blog=models.ForeignKey(TTSServiceModel.TTSService, on_delete=models.CASCADE, blank=True, null=True)
    user=models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

所有登录的用户都可以看到其他用户的博客。当前登录的用户可以“喜欢”某个博客,这会在 UserLikedBlogs 表中添加一个条目。

我现在希望向登录用户显示系统中存在的所有博客,但我也希望显示用户喜欢的博客。

我知道这应该从 Blog 表中获取所有条目,并从 UserLikedBlogs 表中获取其他列,其中数据仅针对用户喜欢的博客存在,否则不存在。

这是外连接的典型案例,其中两个集合之间的公共元素与参与连接的一个表中的所有元素相关联。

我一直在阅读 django 和 SO 上的文档,但我似乎找不到正确的语法来执行此操作。

我目前这样做的 hacky 方法是Pandas在 Python 中使用并加入两个数据集,而不是查询。我确信有更好的方法,但就是找不到。你能帮我吗?

标签: pythondjangodjango-modelsdjango-ormouter-join

解决方案


可能你可以这样尝试:

Blog.objects.filter(userlikedblogs__user=request.user)

在这里,我使用reverse relationbetweenUserLikedBlogsBlog来获取用户喜欢的博客。


根据 OP 在此答案底部添加的评论进行更新:

如果用户喜欢博客,这里基本上你想注释信息。你可以这样做conditional expressions

from django.db.models import Case, Value, BooleanField

blogs = Blog.objects.annotate(
     liked=Case(
         When(userlikedblogs__user=request.user, then=Value(True)),
         default=Value(False),
         output_field=BooleanField(),
     )
)

并使用该博客template(当您通过上下文从视图发送到模板时):

{% for blog in blogs %}
    {% if blog.liked %}
        <a style="background:blue" href="{% url 'blog:detail' blog.pk %}">{{ blog.title }}</a>
    {% else %}
        <a style="background:green" href="{% url 'blog:detail' blog.pk %}">{{ blog.title }}</a>
    {% endif %}
{% endfor %}

推荐阅读