Django中的“行为”模型

时间:2011-11-08 11:53:01

标签: django django-models rating rating-system

我是Django的新手,使用Propel ORM引擎从PHP迁移。 所以这就是我目前在Django中所做的事情。我的网站有几个模型,如

  1. 书,
  2. 出版商,
  3. 注释,
  4. 文章等(不是重点)
  5. 他们每个人都可以 用户喜欢或不喜欢(仅一次)将模型的评级改为+1或-1。

    就PHP而言,我会创建一个行为,例如。 “Rateable”将为原始模型和查询类添加一些字段和方法(如get_rating()order_by_rating()等),并为每个模型创建一个单独的表,例如。 book_rating_history,它将保存每个对象的所有评级,以确定用户是否可以更改评级(或在必要时显示所有对象的评级)。所以我需要做的就是在模型声明中指定“Rateable”行为,这就是全部。其他一切都是自动完成的。

    问题是 - 如何在Django中解决这个问题?如何正确建模?在类似情况下你使用哪种技术?

2 个答案:

答案 0 :(得分:3)

您需要单独存储评级和书籍,类似这样(未经测试)。

from django.contrib.auth.models import User
from django.db import models
from django.db.models import Sum

class BookRating(models.Model):
  user = models.ForeignKey(User)
  book = models.ForeignKey('Book')

  # you'll want to enforce that this is only ever +1 or -1
  rating = models.IntegerField()

  class Meta:
    unique_together = (('user', 'book'),)

class Book(models.Model):
  title = models.CharField(max_length = 50)

  def rating(self):
    return BookRating.objects.filter(book = self).aggregate(Sum('rating'))

unique_together强制每位用户只能对给定的图书评分一次。

然后您可以使用以下内容:

book = Book.objects.get(pk = 1)
rating = book.rating()

如果您遇到问题,请添加评论 - 我没有测试过,但希望这足以让您入门。

如果需要,您可以使用content types避免使用具有单独评级对象的每个对象(图书,出版商,评论,文章)。

或者,您可以考虑查看处理喜欢的现有可重用应用,例如django-likesphileo

答案 1 :(得分:0)

您只能在抽象模型中定义特殊方法(例如投票,get_rating等),然后使用此模型创建“Rateable”模型。

class Rateable(models.Model):

    class Meta:
        abstract = True

    def vote(self, *args, **kwargs):
        ...

    def rating(self, *args, **kwargs):
        ...

class Book(Rateable):
    ...

最好使用单一模型来存储评级数据,这些数据是内容类型,如注意到Dominic Rodger