Modelo de "comportamientos" en Django

Soy nuevo en Django, movido de PHP con Propulsar ORM motor. Entonces, esto es lo que estoy haciendo actualmente en Django. Mi sitio web tiene varios modelos como

  1. Libro,
  2. Editor,
  3. Comentario,
  4. Artículo y así sucesivamente (no es el punto)

Cada uno de ellos puede gustar o no a un usuario (solo una vez) cambiando la calificación del modelo en +1 o -1.

En términos de PHP, crearía un comportamiento, por ejemplo. "Tasable", que agregaría algunos campos y métodos al modelo original y la clase de consulta (como get_rating(), order_by_rating(), etc.) y cree una tabla separada para cada modelo, por ej. book_rating_history que contendría todas las calificaciones para cada objeto, para determinar si el usuario puede o no puede cambiar la calificación (o mostrar todas las calificaciones del objeto, si es necesario). Entonces, todo lo que tendría que hacer es especificar el comportamiento "Tasable" en la declaración del modelo, y eso es todo. Todo lo demás se hace automáticamente.

La pregunta es: ¿cómo resolver esto en Django? ¿Cómo modelar correctamente? ¿Qué técnicas utilizas en casos similares?

preguntado el 08 de noviembre de 11 a las 11:11

2 Respuestas

Querrá almacenar calificaciones y libros por separado, algo como esto (sin probar).

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 obliga a que cada usuario solo pueda calificar un libro determinado una vez.

Luego puede usar esto algo como:

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

Agregue un comentario si tiene problemas con esto; no lo he probado, pero espero que esto sea suficiente para comenzar.

Probablemente pueda evitar que cada objeto (libros, editoriales, comentarios, artículos) tenga un objeto de calificación separado usando tipos de contenido, si tu quieres.

Alternativamente, podría considerar buscar aplicaciones reutilizables existentes que manejen los me gusta, como django-likes or phileo.

respondido 08 nov., 11:16

Característica de bonificación: el usuario puede cambiar su calificación en un momento posterior. - Mike DeSimone

Puede definir métodos especiales (por ejemplo, vote, get_rating, etc.) solo una vez en el modelo abstracto y luego cree sus modelos "evaluables" usando este.

class Rateable(models.Model):

    class Meta:
        abstract = True

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

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

class Book(Rateable):
    ...

También es mejor usar un modelo único para almacenar datos de calificación con tipos de contenido, como lo notó Dominic Rodger.

respondido 08 nov., 11:16

Gracias chicos, leí la documentación del marco de tipos de contenido y decidí usarla para calificaciones, etiquetas y cosas similares. - user655136

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.