【问题标题】:django left join with where clause subexpressiondjango left join with where 子句子表达式
【发布时间】:2017-02-20 08:21:57
【问题描述】:

我目前正在尝试使用 Django (v1.10) ORM 做一些我认为应该可行的方法,但我很难理解如何应用记录的方法来解决我的问题。

编辑:所以这是我一起破解的 sql,以从 dbshell 返回我想要的数据,现在使用 postgresql 数据库,在我意识到我原来的 sqlite3支持的 sql 查询不正确:

select 
    voting_bill.*,vv.vote 
from 
    voting_bill 
left join 
    (select 
        voting_votes.vote,voting_votes.bill_id 
    from 
        voting_bill 
    left join 
        voting_votes 
    on 
        voting_bill.id=voting_votes.bill_id 
    where 
        voting_votes.voter_id = (select id from auth_user where username='richard' or username is Null)
   ) 
as 
    vv 
on 
    voting_bill.id=vv.bill_id;

这是我的投票应用程序的“models.py”:

from django.db import models
from django.contrib.auth.models import User


class Bill(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    result = models.BooleanField()
    status = models.BooleanField(default=False)

    def __str__(self):
        return self.name


class Votes(models.Model):
    vote = models.NullBooleanField()
    bill = models.ForeignKey(Bill, related_name='bill',
                             on_delete=models.CASCADE,)
    voter = models.ForeignKey(User, on_delete=models.CASCADE,)

    def __str__(self):
        return '{0} {1}'.format(self.bill, self.voter)

我可以看到我的 sql 按我预期的方式工作,投票被添加到末尾,或者如果用户尚未投票,则返回 null。

我正在努力使查询集采用这种格式,以便我可以在模板中对其进行迭代以生成一个表,如果结果为空,我可以提供一个链接,将用户带到另一个视图。

我已阅读有关 select_related 和 prefetch_related 的信息,但正如我所说,我正在努力弄清楚如何将其转换为如何在 SQL 中执行此操作。

【问题讨论】:

    标签: python django join django-queryset where-clause


    【解决方案1】:

    希望我正确理解了您的问题。试试这个:

    votes = Votes.objects.filter(voter__username='django').select_related('bill')
    

    你可以使用它。但我认为在这种情况下你不需要select_related

    bills_for_user = Bill.objects.filter(votes__voter__username='django').select_related('votes').distinct()
    

    现在您可以迭代您的 bills_for_user

    for bill in bills_for_user:
        bill_name = bill.name
        bill_description = bill.description
        bill_result = bill.result
        bill_status = bill.status
    
        # and there are several variants what you can with votes
        bill_votes = bill.votes_set.all()  # will return you all votes for this bill
        bill_first_vote1 = bill.votes_set.first() # will return first element in this query or None if its empty
        bill_first_vote2 = bill.votes_set.all()[0] # will return first element in this query or Error if its empty
        bill_last_vote = bill.votes_set.last()[0] # will return last element in this query or None if its empty
        # you can also filter it for example by voting
        bill_positive_votes = bill.votes_set.filter(vote=True) # will return you all votes for this bill with 'vote' = True
        bill_negative_votes = bill.votes_set.filter(vote=False) # will return you all votes for this bill with 'vote' = False
        bill_neutral_votes = bill.votes_set.filter(vote=None) # will return you all votes for this bill with 'vote' = None
    

    【讨论】:

    • 嗯,如果我正确阅读,我认为这不会达到我想要的效果。我想退回所有的账单,但我想像你在那里所做的那样保留对投票的过滤器。我有点想要这样的东西: bills_for_user = Bills.objects.select_related('votes').filter(votes__voter=request.user)
    • 已编辑。现在您可以遍历账单查询集
    • bills = Bill.objects.filter( votes__voter__id=request.user.id).select_related('votes').distinct() Cannot resolve keyword 'votes' into field. Choices are: bill, description, id, name, result, status
    • 由于某种原因,我似乎无法编辑cmets,但是代码后面有错误消息。基本上它似乎不喜欢某处的投票,无论是在选择相关还是在过滤器中。我一直在玩,但大多数时候我无法获得与使用 Bill 模型相关的选择,因为它是 FK 的反面? FK 在投票模型中
    • 已编辑。您的投票模型中缺少“related_name”。它有点迷失方向,因为通常related_name 使用与模型名称相同的名称,以使其在反向关系中更具人类可读性,但在您的情况下,您将拥有带有bill 属性的Bill 实例,这实际上是Votes设置。
    猜你喜欢
    • 2021-02-15
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多