Frage

Ich habe ein ziemlich generisches Artikelmodell mit M2M -Beziehung zum Tag -Modell. Ich möchte die Anzahl der einzelnen Tag -Verwendung beibehalten. Ich denke, der beste Weg wäre es, das Feld des Zählers auf dem Tag -Modell zu verhindern und jedes Mal zu aktualisieren, wenn Artikel gespeichert werden. Wie kann ich das erreichen oder vielleicht gibt es einen besseren Weg?

War es hilfreich?

Lösung

Sie können dies tun, indem Sie eine erstellen Zwischenmodell Für die M2M -Beziehung und verwenden Sie sie als Ihren Haken für die post_save und post_delete signalisiert, um die Denormalisierte Spalte in der zu aktualisieren Article Tisch.

Zum Beispiel mache ich das für Favorited Question zählt in Soclone, wo Users haben eine M2M -Beziehung mit Questions:

from django.contrib.auth.models import User
from django.db import connection, models, transaction
from django.db.models.signals import post_delete, post_save

class Question(models.Model):
    # ...
    favourite_count = models.PositiveIntegerField(default=0)

class FavouriteQuestion(models.Model):
    question = models.ForeignKey(Question)
    user     = models.ForeignKey(User)

def update_question_favourite_count(instance, **kwargs):
    """
    Updates the favourite count for the Question related to the given
    FavouriteQuestion.
    """
    if kwargs.get('raw', False):
        return
    cursor = connection.cursor()
    cursor.execute(
        'UPDATE soclone_question SET favourite_count = ('
            'SELECT COUNT(*) from soclone_favouritequestion '
            'WHERE soclone_favouritequestion.question_id = soclone_question.id'
        ') '
        'WHERE id = %s', [instance.question_id])
    transaction.commit_unless_managed()

post_save.connect(update_question_favourite_count, sender=FavouriteQuestion)
post_delete.connect(update_question_favourite_count, sender=FavouriteQuestion)

# Very, very naughty
User.add_to_class('favourite_questions',
                  models.ManyToManyField(Question, through=FavouriteQuestion,
                                         related_name='favourited_by'))

Über die Mailingliste von Django-Entwicklern wurde ein wenig über die Implementierung einer Mittel zur deklarativen Deklarierung der Denormalisierung geführt, um nicht so beschrieben zu werden:

Andere Tipps

Dies ist eine neue Funktion in Django 1.2:http://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top