django使用where子表达式离开连接

时间:2016-10-11 17:34:56

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

我目前正试图找到一种方法来处理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。

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

我已经阅读了有关select_related和prefetch_related的内容,但正如我所说,我正在努力解决如何将其转换为如何在SQL中执行此操作。

1 个答案:

答案 0 :(得分:0)

希望我能正确理解你的问题。试试这个:

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