Create a model with a ForeignKey and another field

1

I wish you a good start to the week and I take this opportunity to ask a question about the implementation of my model in django 1.9 using mysql:

I have a catalog of authors and each one has a unique id, each author participates in one or several works, and additionally, there is a field of order of mention within the work.

Initially I thought that the "order" field (of order of appearance in the work) should be in the Authors table, something like this:

class Autor(models.Model):
orden = models.CharField(max_length=2)
nombre = models.CharField(max_length=40)
primer_apellido = models.CharField(max_length=40)
segundo_apellido = models.CharField(max_length=40,blank=True)
correo = models.EmailField(blank=True)
institucion = models.CharField(max_length=200)

class Meta:
    ordering = ["primer_apellido"]
    verbose_name_plural ="Autores"

def __str__(self):
        return '%s %s %s' %(self.nombre, self.primer_apellido, self.segundo_apellido)

but then I realized that the one you put in the authors table, the order in which it appears in a job, will not allow me to use the same author's record in another job, since it might have another order within the second work -order, refers rather to the position in which his name is mentioned within the work, the main author is 1, the second author has the order 2, etc .-

I know I need an intermediate table so that the authors, the works and the order thereof are related, so my model would be something like this:

class Contribucion(models.Model):
autores = models.ForeignKey(Autor)
orden_autor = models.ForeignKey(Autor.orden)
trabajo = models.ForeignKey(Trabajo)

But when doing check from manage.py, it returns the error: AttributeError: type object 'Autor' has no attribute 'orden'

The question is: how could the order field be included in the model so that when retrieving the records from the table, the order of mention of the authors does so by establishing an ascending order with that field.

Thank you very much in advance for your support.

Gustavo.

    
asked by Gustux 25.07.2016 в 21:59
source

1 answer

1

The orden_autor field does not have to be a foreign key. It suffices that it is a simple numerical field or a letter that allows its ordering.

Why? Each record in the Contribucion table consists of a unique combination of author and order.

  

Although with a little order in the job log, the field id of the table Contribución would do the magic. Anyway.

Look at this example:

from django.db import models

class Autor(models.Model):
  nombre = models.CharField(max_length=40)

class Trabajo(models.Model):
  nombre = models.CharField(max_length=40)

class Contribucion(models.Model):
  trabajo = models.ForeignKey(Trabajo)
  autor = models.ForeignKey(Autor)
  orden = models.IntegerField()

  class Meta:
    unique_together = ("trabajo", "orden")

As you can see, orden is just a number field, but the model has a composite index between trabajo and orden , so that a job does not have two number 1, for example.

By checking the model, we can see the following.

>>> from arte.models import Trabajo, Autor, Contribucion
>>> t = Trabajo(nombre="algo")
>>> a1 = Autor(nombre="Fulano")
>>> a2 = Autor(nombre="Sutano")
>>> c1 = Contribucion(trabajo=t, autor=a1, orden=1)
>>> c2 = Contribucion(trabajo=t, autor=a2, orden=1)
>>> t.save()
>>> a1.save()
>>> a2.save()
>>> c1.save()

But when saving c2 that repeats the same order number and the same job, we get an error:

>>> c2.save()
…
django.db.utils.IntegrityError: UNIQUE constraint failed: arte_contribucion.trabajo_id, arte_contribucion.orden

If we change the value of orden in c2 and re-save, we no longer have problems ...

>>> c2 = Contribucion(trabajo=t, autor=a2, orden=2)
>>> c2.save()
>>> c2
<Contribucion: Contribucion object>
>>> c2.id
2

My opinion is that the field orden should not be a foreign key, but a simple numeric field, which makes all your models simpler.

The reference, with version 1.9 of Django: link

    
answered by 25.07.2016 / 22:39
source