我是Django的新手,使用Propel ORM引擎从PHP迁移。 所以这就是我目前在Django中所做的事情。我的网站有几个模型,如
他们每个人都可以 用户喜欢或不喜欢(仅一次)将模型的评级改为+1或-1。
就PHP而言,我会创建一个行为,例如。 “Rateable”将为原始模型和查询类添加一些字段和方法(如get_rating()
,order_by_rating()
等),并为每个模型创建一个单独的表,例如。 book_rating_history
,它将保存每个对象的所有评级,以确定用户是否可以更改评级(或在必要时显示所有对象的评级)。所以我需要做的就是在模型声明中指定“Rateable”行为,这就是全部。其他一切都是自动完成的。
问题是 - 如何在Django中解决这个问题?如何正确建模?在类似情况下你使用哪种技术?
答案 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-likes或phileo。
答案 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