在django 1.2中:
我有一个带有额外参数的查询集,该参数引用了一个表,该表当前未包含在django为此查询集生成的查询中。
如果我将order_by添加到引用另一个表的queryset,则django以正确的方式将连接添加到另一个表,并且额外的工作。但是没有order_by,额外的参数就会失败。我可以在另一个表中添加一个无用的二级order_by,但我认为应该有更好的方法来实现它。
以合理的方式添加联接的django函数是什么?我知道这必须在某个地方被召唤。
以下是一些示例代码。它选择给定用户的所有读数,并使用存储在“朋友”中的另一个用户给出的评级(如果有)来注释结果。
class Book(models.Model):
name = models.CharField(max_length=200)
urlname = models.CharField(max_length=200)
entrydate=models.DateTimeField(auto_now_add=True)
class Reading(models.Model):
book=models.ForeignKey(Book,related_name='readings')
user=models.ForeignKey(User)
rating=models.IntegerField()
entrydate=models.DateTimeField(auto_now_add=True)
readings=Reading.objects.filter(user=user).order_by('entrydate')
friendrating='(select rating from proj_reading where user_id=%d and \
book_id=proj_book.id and rating in (1,2,3,4,5,6))'%friend.id
readings=readings.extra(select={'friendrating':friendrating})
目前,读数无法正常工作,因为未正确设置读数连接。但是,如果我通过以下方式添加订单:
.order_by('entrydate','reading__entrydate')
django神奇地知道通过外键添加内部联接,我得到了我想要的东西。
其他信息:
print readings.query ==>
select ((select rating from proj_reading where user_id=2 and book_id=proj_book.id and rating in (1,2,3,4,5,6)) as 'hisrating', proj_reading.id, proj_reading.user_id, proj_reading.rating, proj_reading.entrydate from proj_reading where proj_reading.user_id=1;
假设 user.id = 1 friend.id = 2
错误是:
OperationalError: Unknown column proj_book.id in 'where clause'
并且它发生是因为表proj_book未包含在查询中。重申我上面所说的 - 如果我现在读readings2 = readings.order_by('book__entrydate')我可以看到正确的连接已设置并且查询有效。
理想情况下,我只想弄清楚qs.query函数的名称是什么,它会查看两个表,并确定它们是如何通过外键连接的,只需手动调用即可。
答案 0 :(得分:1)
您生成的查询:
选择((从proj_reading中选择等级,其中user_id = 2,book_id = proj_book .id并在(1,2,3,4,5,6)中评级为'hisrating',proj_reading来自proj_reading的.id,proj_reading.user_id,proj_reading.rating,proj_reading.entrydate,其中proj_reading.user_id = 1;
db无法理解proj_book的含义,因为它不包含在(来自表或内连接)中。
当你添加order_by时,你得到了预期的结果,因为order_by查询是在proj_book和proj_reading之间添加内连接。
据我了解,如果您推荐Book中的任何其他专栏,而不仅仅是order_by,您将得到类似的结果。
这样,在步骤Q1,您强制DJango在Book表上添加连接,这不是默认值,除非您访问Book表的任何字段。
答案 1 :(得分:0)
class SomeModel(models.Model)
id = models.IntegerField()
...
class SomeOtherModel(models.Model)
otherfield = models.ForeignKey(SomeModel)
qrst = SomeOtherModel.objects.filter(otherfield__id=1)
您可以使用“__”创建表连接。
编辑: 它不会工作,因为你没有正确定义表连接。
myrating='(select rating from proj_reading inner join proj_book on (proj_book.id=proj_reading_id) where proj_reading.user_id=%d and rating in (1,2,3,4,5,6))'%user.id)'
这是一个pesdocode,未经过测试。
但是,我建议你使用django过滤器而不是编写SQL查询。
read = Reading.objects.filter(book__urlname__icontains="smith", user_id=user.id, rating__in=(1,2,3,4,5,6)).values('rating')
Documentation了解详情。