2009-12-24 10 views
4

J'ajoute des champs date_added et date_modified à un tas de modèles courants dans mon projet actuel. Je sous-classe models.Model et ajoute les champs appropriés, mais je veux ajouter un comportement d'enregistrement automatisé (ie: chaque fois que quelqu'un appelle MyModel.save(), le champ date_modified est mis à jour.) Je vois deux approches: surcharger la méthode save() ou l'ajout d'un gestionnaire de signal pre_save dans la classe de base abstraite.Meilleure façon d'ajouter du datum_added commun, date_modified à de nombreux modèles dans Django

class CommonData(models.Model): 
    date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False) 
    date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True) 

    # register a handler for the pre_save to update date_modified 
    def pre_save_handler(sender, **kwargs): 
     date_modified = datetime.datetime.today 

    def __init__(): 
     pre_save.connect(pre_save_handler, sender=self) 

ou

class CommonData(models.Model): 
    date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False) 
    date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True) 

    # overriding save 
    def save(force_insert=False,force_update=False): 
     date_modified = datetime.datetime.now 
     return models.Model.save(force_insert, force_update) 

Je suis nouveau à Django et Python et je me demandais quelle approche était plus « django »? Ce qui est plus efficace? qui est le "bon" moyen de le faire?

Répondre

4

Puisque vous êtes nouveau à Django, vous pouvez trouver les extensions de commande Django utile:

http://code.google.com/p/django-command-extensions/

... qui comprend commodément un TimeStampedModel vous pouvez déduire vos modèles de:

http://code.google.com/p/django-command-extensions/wiki/ModelExtensions

Un modèle de classe de base abstrait qui fournit des champs "créés" et "modifiés" autogérés.

+0

merci prometheus, je n'étais pas au courant des extensions de commande. Je coeur python/django ... cependant, il y a plusieurs façons de faire les choses! – Deano

2

Vous pouvez def les dans un Abstract Base Class puis héritent de cela. C'est un peu comme avoir un MixIn qui définit également les champs de modèle.

+0

Merci Peter, c'est ce que je faisais, ma question était un peu plus sur la meilleure façon d'implémenter la fonctionnalité par défaut: signaux verus méthode overrides. Je suppose que le signal ressemble plus à un mixin et que la méthode override ressemble plus à une fonctionnalité par défaut non? – Deano

+0

Vous avez raison, je passais au jeûne sans assez de caféine. La réponse de Kibitzer est morte. –

4

Avez-vous essayé en regardant DateTimeFieldauto_now=True et auto_now_add=True? Ils font exactement ce dont vous avez besoin automatiquement. Sinon, il n'y a pas vraiment de différence entre la sauvegarde et la gestion des signaux - en fait, le signal pre_save est appelé depuis la méthode save du modèle django.

Docs: http://docs.djangoproject.com/en/dev/ref/models/fields/#datefield

+0

génial, merci kibitzer! oui je suppose que je devrais rtfm'd – Deano

+0

auto_now et auto_now_add sont considérés comme non fiables maintenant. Mieux vaut définir les dates dans la méthode save. C'est ce que les autres solutions suggérées (avec ABC) utilisent. – hopla

1

Notez que auto_now_add et auto_now utilise pre_save, qui ne fonctionne pas lorsque bulk_create ou update. Ainsi, dans votre MySQL, par exemple, le champ date_added sera '0000-00-00 00:00:00' et il est possible d'avoir un avertissement: 'Attention: La colonne' date_added 'ne peut pas être nulle'. Vous pouvez donc utiliser auto_now * mais vous devez faire attention.