Tenho um modelo que gostaria que contivesse o nome do sujeito e suas iniciais (os dados são um tanto anônimos e rastreados por iniciais).
Agora mesmo, eu escrevi
class Subject(models.Model):
name = models.CharField("Name", max_length=30)
def subject_initials(self):
return ''.join(map(lambda x: '' if len(x)==0 else x[0],
self.name.split(' ')))
# Next line is what I want to do (or something equivalent), but doesn't work with
# NameError: name 'self' is not defined
subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials)
Conforme indicado pela última linha, eu preferiria poder ter as iniciais realmente armazenadas no banco de dados como um campo (independente do nome), mas que seja inicializado com um valor padrão baseado no campo de nome. No entanto, estou tendo problemas porque os modelos de django não parecem ter um 'eu'.
Se eu mudar a linha para subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials)
, posso fazer o syncdb, mas não consigo criar novos assuntos.
Isso é possível no Django, tendo uma função chamável dar um padrão para algum campo com base no valor de outro campo?
(Para os curiosos, o motivo pelo qual desejo separar as iniciais da minha loja separadamente é em casos raros em que sobrenomes estranhos podem ter diferentes daqueles que estou rastreando. Por exemplo, outra pessoa decidiu que as iniciais do Assunto 1 Chamado "John O'Mallory" são "JM" em vez de "JO" e deseja corrigir, edite-o como administrador.)
fonte
super().save(*args, **kwargs)
(sem osSubject, self
argumentos) como no exemplo da documentação referenciada.Não sei se existe uma maneira melhor de fazer isso, mas você pode usar um manipulador de sinal para o
pre_save
sinal :fonte
post_save
vez depre_save
.**kwargs
argumento que todas as funções do receptor deveriam ter de acordo com docs.djangoproject.com/en/2.0/topics/signals/… ?save()
, talvez alterada para substituição__init__
, é melhor porque é mais explícita.Usando sinais do Django , isso pode ser feito bem cedo, recebendo o
post_init
sinal do modelo.O
post_init
sinal é enviado pela classe assim que ela tiver feito a inicialização na instância. Dessa forma, a instância obtém um valor paraname
antes de testar se seus campos não anuláveis estão definidos.fonte
save()
, talvez alterada para substituição__init__
, é melhor porque é mais explícita.Como uma implementação alternativa da resposta de Gabi Purcaru , você também pode se conectar ao
pre_save
sinal usando oreceiver
decorador :Esta função de receptor também aceita os
**kwargs
argumentos de palavra-chave curinga que todos os manipuladores de sinal devem usar de acordo com https://docs.djangoproject.com/en/2.0/topics/signals/#receiver-functions .fonte