通过django中的自定义模型字段进行排序

时间:2011-07-24 12:08:15

标签: django django-models

我正在尝试为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中,因为有各种过滤器,需要多个语句。

我到底该怎么做?谢谢。

3 个答案:

答案 0 :(得分:1)

我的反应是,你试图吃一口比咬你更大的东西。通过为自己提供更多的原始资料,将其分解为一口大小。

您想分别创建这两个部分,以便您可以调用它们:

  • 此用户是否会对此视频获得赞誉? return boolean
  • 这位用户可以获得多少视频? return int

然后使用@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 ...希望它有所帮助!