1

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

  1. 书,
  2. 出版商,
  3. 评论,
  4. 文章等(这不是重点)

用户可以喜欢或不喜欢它们中的每一个(仅一次),将模型的评分更改为 +1 或 -1。

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

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

4

2 回答 2

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

于 2011-11-08T12:20:58.737 回答
0

您可以仅在抽象模型中定义特殊方法(例如 vote、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 所注意到的,最好使用单一模型来存储内容类型的评级数据

于 2011-11-08T12:46:37.317 回答