Модель "Поведения" в Джанго - PullRequest
1 голос
/ 08 ноября 2011

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

  1. Book,
  2. Publisher,
  3. Comment,
  4. Article и так далее (это не главное)

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

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

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

Ответы [ 2 ]

3 голосов
/ 08 ноября 2011

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

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 или phileo .

0 голосов
/ 08 ноября 2011

Вы можете определять специальные методы (например, голосование, get_rating и т. Д.) Только в абстрактной модели, а затем создавать свои "Оцениваемые" модели, используя этот.

class Rateable(models.Model):

    class Meta:
        abstract = True

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

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

class Book(Rateable):
    ...

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

...