2009-02-07 9 views
19

Actualmente estoy codificando un sitio en Django (¡porque nunca se pueden aprender demasiados frameworks!), Y me pregunto si hay una manera de autoincrementar un objeto con respecto a un objeto relacionado. Así, por ejemplo, decir que tengo un modelo de entrada y un modelo de EntryVersion:¿Hay alguna manera de autoincrementar un campo de Django con respecto a una clave externa?

entrada
- título
- babosa

EntryVersion
- entrada (clave externa)
- version_number
- contenido

Quiero autoincrementar version_number con respecto a la clave foránea de entrada (para que una entrada tenga varias versiones, comenzando en una y moviéndose hacia arriba en una). Sin embargo, no será un verdadero autoincremento, ya que no será único en la base de datos (puede haber muchas versiones de entrada con version_number = 1, solo una para una entrada determinada).

Sé que podría rodar mi propio administrador y solo manejar esto allí, pero me preguntaba si había alguna manera de que el administrador de Django aumente automáticamente el número de versión cada vez que se guarde una nueva versión de entrada.


Editar: código específico que he usado (corregido al número de versión sólo se establece en primer salvamento)

respuesta de Tiago tenía razón, pero en interés de los futuros usuarios stackoverflow con dilemas similares, aquí está la código específico que he utilizado:

def save(self, force_insert=False, force_update=False): 
    # Only modify number if creating for the first time (is default 0) 
    if self.version_number == 0: 
     # Grab the highest current index (if it exists) 
     try: 
      recent = EntryVersion.objects.filter(entry__exact=self.entry).order_by('-version_number')[0] 
      self.version_number = recent.version_number + 1 
     except IndexError: 
      self.version_number = 1 
    # Call the "real" save() method 
    super(EntryVersion, self).save(force_insert, force_update) 

el truco order_by w/index es uno que extraer de la documentación de Django aquí:

http://docs.djangoproject.com/en/dev/topics/db/queries/#id4

Tenga en cuenta que debe tener default=0 definido en su campo version_number para que esto funcione.

Puede haber una manera mejor, pero esto parece estar funcionando exactamente de la manera que necesitaba; con suerte, otros también lo encontrarán útil.

+0

Gracias por compartir su solución. – Giacomo

+1

¿Qué tan segura es esta solución, dadas las solicitudes concurrentes a la misma entrada? –

+0

No estoy seguro de que esté 100% interesado en su caso de uso. ¿Podrías hacer esto en el método de guardar de la Entrada? –

Respuesta

8

Usted puede hacer esto:

def save(self, force_insert=False, force_update=False): 
    #if self.id is None: 
    self.version_number += 1 

    super(EntryVersion, self).save(force_insert, force_update) # Call the "real" save() method. 

que viene directamente desde aquí:

http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods

+0

Gracias! Obviamente, tendré que añadir un poco más de lógica que solo incrementar el número de versión (ya que presumiblemente no será el último número de versión), pero creo que esa es definitivamente la dirección en la que debo dirigirme; gracias también por el enlace, no lo noté en los documentos. –

+0

Hice algo así en un proyecto, pero terminé poniendo la lógica dentro de la vista, ya que era más simple y solo había un método que podía crear mi objeto. – Tiago

+0

Podría terminar migrando a la vista, pero específicamente quería poder tener este Just Work en el administrador en este momento (ya que estoy en las primeras etapas de prueba y todavía no tengo configuración de vistas de edición). ¡Gracias de nuevo! –

Cuestiones relacionadas