开发者

Django generic relation problem

I'm having problems coming up with a filter in one of my views. I'm creating a site with blog entries, news articles, and reviews. The entries and articles have generic relations with the reviews, because the reviews can tag either of them. What I'm trying开发者_如何学编程 to do is to sort the entries/articles based on the sum of the ratings of reviews newer than a certain date.

Here are the simplified models:

class Entry(models.Model):
    name = models.CharField(max_length=50)
    reviews = generic.GenericRelation(Review)

class Article(models.Model):
    name = models.CharField(max_length=50)
    reviews = generic.GenericRelation(Review)

class Review(models.Model):
    rating = models.IntegerField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    target = generic.GenericForeignKey('content_type', 'object_id')
    timestamp = models.DateTimeField(auto_now_add=True)

So, given that I needed to find a sum, I tried using annotate and aggregate, but I ran into two problems. The first one is that apparently generic relations and annotations don't work nicely together: https://code.djangoproject.com/ticket/10461. The second issue is that I don't think it's possible to only sum part of the reviews (in this case, with timestamp__gte=datetime.now()). Am I doing this the wrong way?

I also thought about doing this the other way around:

Review.filter(timestamp__gte=datetime.now(), target__in=something).aggregate(Sum('rating'))

But since I'm trying to order the reviews based on this, don't I need to start with Review.something so I can use order_by?

Thanks.


I would highly suggest using Multi-table inheritance instead of generic foreign keys:

class ReviewedItem(models.Model):
    item_type = models.IntegerField() # exclude me on admin
    def save(self):
        self.item_type = self.ITEM_TYPE
        super(ReviewedItem, self).save()

class Entry(ReviewedItem):
    ITEM_TYPE = 1
    name = models.CharField(max_length=50)

class Article(ReviewedItem):
    ITEM_TYPE = 2
    name = models.CharField(max_length=50)

class Review(models.Model):
    item = models.ForeignKey(ReviewedItem)
    rating = models.IntegerField()
    timestamp = models.DateTimeField(auto_now_add=True)


After doing some research, I found out that the only way to solve my problem was to write custom sql using the "extra" method of QuerySets.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜