Domanda

Snippet preso da questa domanda

from django.db.models import F
...
MyModel.objects.filter(id=...).update(hit_count=F(hit_count)+1)

E 'stato suggerito di mettere nel middleware e ho letto un po' su middleware ma apprezzo molto se qualcuno potrebbe indicare che cosa farebbero in questa situazione. Utilizzando il mio modello Bug come esempio ha un campo slug unico e il pk.

Ecco il mio modello:

class Bug( models.Model ):
    name = models.CharField( max_length=100 )
    slug = models.SlugField(unique=True)
    excerpt = models.TextField()
    excerpt_markdown = models.TextField( editable=False, blank=True )
    summary = models.TextField()
    summary_markdown = models.TextField(editable=False, blank=True)
    #workaround = models.TextField()
    #workaround_markdown = models.TextField(editable=False, blank=True)
    date_added = models.DateTimeField()
    poster = models.ForeignKey(User)
    tags_string = TagField()

    class Meta:
    ordering = ['name']

    def __unicode__(self):
    return self.name

    def get_absolute_url(self):
    return '/bugs/%s/' % self.slug

    def save( self, force_insert=False, force_update=False ):
    self.summary_markdown = markdown(  self.summary  )
    self.excerpt_markdown = markdown ( self.excerpt )
    #self.workaround_markdown = markdown(  self.workaround )
    super( Bug, self ).save( force_insert, force_update )

I collegamenti sono visualizzati attraverso /bugs/(slug). Ho ancora per aggiungere la nuova colonna, ma immagino che sia solo hit_counter = models.IntegerField()

È stato utile?

Soluzione

Sono disponibili tre opzioni:

  1. Inserire il codice in un middleware in modo che sia universalmente disponibile nel modello attraverso il RequestContext.

  2. Inserire il codice in un decoratore (essenzialmente solo una funzione di pitone che avvolge un'altra funzione e aggiunge alcune funzionalità) in modo che si può decidere dove si desidera che questo codice "conteggi" da applicare.

  3. Inserire il codice in un modello personalizzato tag che incrementare il contatore ogni volta che un modello con il tag viene reso.

Opzione tre (tag template) è il più complicato, ma il più adatto per lo scopo effettivo in quanto può rendere il bancone e incrementarlo in un unico pezzo di codice. Opzione 1 (middleware) è il più facile, ma anche la meno flessibili / riutilizzabili, ecc.

Middleware e template tags sono entrambi ben documentati nella documentazione di Django. Otterrete molto di più di lavorare attraverso di loro di quello che sarà fuori di ottenere consegnato un frammento di codice qui su SO.

Decoratori sono una parte fondamentale di Python dal v2.4, e sono l'apprendimento vale la pena, ma non la soluzione che sceglierei qui. Sono uno strumento potente e una ricerca su Google (o anche una ricerca su SO) vi darà tonnellate di informazioni.

Altri suggerimenti

E 'probabilmente la pena sottolineare che se si salva il modello ogni volta che un utente visualizza, questo è intenzione di rendere la maggior parte delle cache inutile, dal momento che il modello sarà più fresco rispetto a qualsiasi cache.

Se questo è importante per voi, si può prendere in considerazione un approccio che preserverà il caching - per esempio, aggiornare un modello Hits separato su ogni vista, invece, quindi piegare quei conteggi colpito di nuovo nel modello principale a intervalli di cache-friendly.

Io preferisco metterlo all'interno del decoratore e decorare tutti i punti di vista che accedono a questo modello

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top