BOMBOLOM.COM

(django) Compose Field and set Unique

Este é um post de José Lopes.

Este post exemplifica como criar um modelo no Django com um atributo composto por outros dois, assegurando a unicidade do mesmo.

Vamos imaginar que temos o seguinte modelo:

class ExampleModel( models.Model ):
    first_part = models.ForeignKey(OtherModel)
    second_part = models.CharField(max_length=8)
    fullname = models.CharField(max_length=19, blank=True, editable=False)

    def save(self):
    	self.fullname = '%s-%s' % (self.first_part, self.second_part)
        super(ExampleModel,self).save()

Neste modelo temos o atributo fullname, que não é editável na página de administração, mas é criado sobrepondo o método de gravação (save) seguindo uma determinada forma com base nos atributos first_part e second_part.

Isto segue os exemplos que se encontram facilmente pela web. Propositadamente incluí dois atributos em que um deles é uma ForeignKey só para mostrar que podemos ter qualquer tipo de campo, embora é claro que um ManyToMany não faz sentido para este caso.

Agora quero ainda que este atributo fullname seja único, sendo este o assunto que queria abordar neste post.

Podemos ter a tentação de incluir a unicidade directamente no atributo:

fullname = models.CharField(max_length=19, blank=True, editable=False, unique=True)

Isto põe-nos um problema que é o de múltiplos acessos à nossa aplicação. Como por defeito o atributo é nulo (None), vai-nos causar problemas nos acessos simultâneos respondendo com mensagens de erro em que diz que o valor tem de ser único. Isto claro que não é aceitável.

A solução é bastante simples, recorrendo à classe Meta. O nosso modelo ficaria:

class ExampleModel( models.Model ):
    first_part = models.ForeignKey(OtherModel)
    second_part = models.CharField(max_length=8)
    fullname = models.CharField(max_length=19, blank=True, editable=False)

    class Meta:
        unique_together = (('first_part', 'second_part'))

    def save(self):
    	self.fullname = '%s-%s' % (self.first_part, self.second_part)
        super(ExampleModel,self).save()

O código em vermelho faz a magia de garantir a unicidade dos atributos first_part e second_part, o que nos serve perfeitamente pois ambos constituem o atributo fullname que queremos que seja único.

23.05.2008 | Ler mais | Comentários | Tags ,

Voltar à Página principal | Made with PyBlosxom