我正在尝试为django模型添加其他自定义字段。我一直很难搞清楚如何做以下事情,并且我会在第一个完全正确的答案时获得150pt赏金(当它可用之后) - 见参考Improving Python/django view code)。
我有以下模型,自定义def为每个用户返回视频计数 -
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
positions = models.ManyToManyField('Position', through ='PositionTimestamp', blank=True)
def count(self):
from django.db import connection
cursor = connection.cursor()
cursor.execute(
"""SELECT (
SELECT COUNT(*)
FROM videos_video v
WHERE v.uploaded_by_id = p.id
OR EXISTS (
SELECT NULL
FROM videos_videocredit c
WHERE c.video_id = v.id
AND c.profile_id = p.id
)
) AS Total_credits
FROM userprofile_userprofile p
WHERE p.id = %d"""%(int(self.pk))
)
return int(cursor.fetchone()[0])
我希望能够通过点票订购,即UserProfile.objects.order_by('count')
。当然,我不能这样做,这就是我提出这个问题的原因。
以前,我尝试添加自定义模型管理器,但问题是我还需要能够按UserProfile模型的各种标准进行过滤:具体来说,我需要能够执行:UserProfile.objects.filter(positions=x).order_by('count')
。另外,我需要留在ORM中(不能有原始的sql输出),我不想把过滤逻辑放到SQL中,因为有各种过滤器,需要多个语句。
我到底该怎么做?谢谢。
答案 0 :(得分:1)
我的反应是,你试图吃一口比咬你更大的东西。通过为自己提供更多的原始资料,将其分解为一口大小。
您想分别创建这两个部分,以便您可以调用它们:
然后使用@property,模型管理器,查询集和方法的组合,最简单地表达您的需求。
例如,您可以将“信用”附加到采用用户参数的视频模型,或者采用视频参数的用户模型,或者为用户添加“信用”管理器,这会增加他们信用的视频数量。
这不是微不足道的,但如果你为之努力,不应该太棘手。
答案 1 :(得分:0)
“你不能使用类似”额外“查询集修饰符的东西吗?”
请参阅docs
起初我没有把它放在一个答案中,因为我不确定它是否真的有用,或者它是否是你所需要的 - 它更像是在(希望)正确的方向上轻推。
在该页面的文档中有一个示例
<强>查询强>
Blog.objects.extra( select={ 'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id' }, )
结果sql
SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count FROM blog_blog;
也许做类似的事情,并访问您当前拥有的用户ID,如p.id appname_userprofile.id
注意:强>
我只是翼了它所以试着玩一下。 也许使用shell将查询输出为sql,看看你得到了什么。
答案 2 :(得分:0)
模型:
class Positions(models.Model):
x = models.IntegerField()
class Meta:
db_table = 'xtest_positions'
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
positions = models.ManyToManyField(Positions)
class Meta:
db_table = 'xtest_users'
class Video(models.Model):
usr = models.ForeignKey(UserProfile)
views = models.IntegerField()
class Meta:
db_table = 'xtest_video'
结果:
test = UserProfile.objects.annotate(video_views=Sum('video__views')).order_by('video_views')
for t in test:
print t.video_views
doc:https://docs.djangoproject.com/en/dev/topics/db/aggregation/
这是你想要的,或者我完全被误解了!.. Anywhoo ...希望它有所帮助!