Поведение моделей в Django

Я новичок в Django, перешел с PHP на движок Propel ORM. Итак, вот что я сейчас делаю в Django. На моем сайте есть несколько моделей, таких как

  1. Книга,
  2. Издатель,
  3. Комментарий,
  4. Статья и тд (не суть)

Каждый из них может понравиться или не понравиться пользователю (только один раз), изменив рейтинг модели на +1 или -1.

С точки зрения PHP я бы создал поведение, например. «Rateable», который добавит некоторые поля и методы к исходной модели и классу запроса (например, get_rating(), order_by_rating() и т. д.) и создаст отдельную таблицу для каждой модели, например. book_rating_history, который будет содержать все рейтинги для каждого объекта, чтобы определить, может ли пользователь изменить рейтинг (или показать все рейтинги объекта, если это необходимо). Так что все, что мне нужно сделать, это указать поведение «Rateable» в объявлении модели, и все. Все остальное делается автоматически.

Вопрос - как это решить в Django? Как правильно моделировать? Какие методы вы используете в подобных случаях?


person user655136    schedule 08.11.2011    source источник


Ответы (2)


Вы захотите хранить рейтинги и книги отдельно, что-то вроде этого (не проверено).

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()

Добавьте комментарий, если у вас есть проблемы с этим - я не проверял это, но, надеюсь, этого достаточно, чтобы вы начали.

Вероятно, вы можете избежать того, чтобы каждый объект (книги, издатели, комментарии, статьи) имел отдельный объект рейтинга, используя типы контента, если хотите.

В качестве альтернативы вы можете рассмотреть существующие многоразовые приложения, которые обрабатывают лайки, такие как django-likes или филео.

person Dominic Rodger    schedule 08.11.2011
comment
Бонусная функция: пользователь может изменить свой рейтинг позже. - person Mike DeSimone; 08.11.2011

Вы можете определить специальные методы (например, voice, get_rating и т. д.) только один раз в абстрактной модели, а затем создавать свои модели «Rateable», используя это.

class Rateable(models.Model):

    class Meta:
        abstract = True

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

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

class Book(Rateable):
    ...

Также лучше использовать единую модель для хранения рейтинговых данных с типами контента, как заметил Доминик Роджер.

person Shamanu4    schedule 08.11.2011
comment
Спасибо, ребята, я прочитал документацию по фреймворку типов контента и решил использовать его для рейтингов, тегов и тому подобного. - person user655136; 16.11.2011