Django sinaliza vs substituindo método save

votos
62

Estou tendo problemas envolvendo minha cabeça em torno deste. Agora eu tenho alguns modelos que olha o tipo de como este:

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

Uma revisão é tem vários scores, a overall_score é a média das pontuações. Quando uma revisão ou uma pontuação é salvo, eu preciso recalcular a média overall_score. Agora eu estou usando um sobrescrito método Save. Haveria quaisquer benefícios a usar despachante sinal de Django?

Publicado 04/10/2008 em 14:37
fonte usuário
Em outras línguas...                            


6 respostas

votos
69

Salvar / apagar os sinais são geralmente favoráveis ​​em situações onde você precisa de fazer mudanças que não são completamente específicos para o modelo em questão, ou poderiam ser aplicadas aos modelos que têm algo em comum, ou pode ser configurado para uso em modelos.

Uma tarefa comum na substituídos savemétodos é automatizado geração de lesmas de algum campo de texto em um modelo. Isso é um exemplo de algo que, se for necessário para implementá-lo para uma série de modelos, iria beneficiar do uso de um pre_savesinal, onde o manipulador de sinal poderia levar o nome do campo de lesma e o nome do campo para gerar a lesma de. Uma vez que você tem algo parecido com isso no lugar, qualquer funcionalidade melhorada você colocar no lugar também se aplicam a todos os modelos - por exemplo, olhando para cima a lesma que está prestes a adicionar para o tipo de modelo em questão, para garantir a exclusividade.

aplicações reutilizáveis ​​muitas vezes se beneficiar do uso de sinais - se a funcionalidade que eles fornecem pode ser aplicado a qualquer modelo, eles geralmente (a menos que seja inevitável) não deseja que os usuários têm para modificar diretamente seus modelos, a fim de beneficiar-se dele.

Com django-mptt , por exemplo, eu usei o pre_savesinal para gerir um conjunto de campos que descrevem uma estrutura de árvore para o modelo que está prestes a ser criado ou atualizado e o pre_deletesinal para remover árvores detalhes estrutura para o objeto que está sendo excluído e sua inteira sub-árvore de objetos antes e eles são excluídos. Devido ao uso de sinais, os usuários não têm para adicionar ou modificar saveou deletemétodos em seus modelos para ter esse gerenciamento feito por eles, eles apenas tem que deixar django-mptt saber quais os modelos que eles querem para gerir.

Respondeu 05/10/2008 em 09:38
fonte usuário

votos
12

Você perguntou:

Haveria quaisquer benefícios a usar despachante sinal de Django?

Eu encontrei este na documentação do Django:

métodos modelo substituídas não são chamados em operações em massa

Note-se que o método de eliminação () para um objecto não é necessariamente chamado quando a eliminação de objectos em massa usando um QuerySet ou como um resultado de uma eliminação em cascata. Para garantir a lógica de exclusão personalizado é executado, você pode usar pre_delete e / ou sinais post_delete.

Infelizmente, não há uma solução alternativa ao criar ou atualizar objetos em massa, uma vez que nenhum de save (), pre_save e post_save são chamados.

De: Substituindo métodos modelo predefinidos

Respondeu 09/03/2016 em 10:10
fonte usuário

votos
3

Se você vai usar sinais de que você seria capaz de atualizar marcar revisão cada modelo de pontuação relacionada tempo fica guardado. Mas se não precisa de tal funcionalidade não vejo qualquer razão para colocar isso em sinal, isso é muito material relacionado com o modelo.

Respondeu 04/10/2008 em 14:55
fonte usuário

votos
2

É uma espécie tipo de desnormalização. Olhe para esta solução bastante . Definição no local campo composição.

Respondeu 04/10/2008 em 16:21
fonte usuário

votos
1

Além pequeno de docs Django sobre exclusão em massa ( .delete()método em QuerySetobjetos):

Tenha em mente que esta vontade, sempre que possível, ser executado puramente em SQL, e assim o delete () métodos de instâncias de objeto individuais não vai necessariamente ser chamado durante o processo. Se você forneceu um costume excluir () método em uma classe de modelo e quer garantir que ele é chamado, você precisará “manualmente” excluir instâncias desse modelo (por exemplo, por iteração sobre um QuerySet e chamando delete () em cada objeto individualmente), em vez de utilizar a maior excluir método () de um QuerySet.

https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects

E atualização em massa ( .update()método em QuerySetobjetos):

Finalmente, percebemos que update () faz uma atualização no nível do SQL e, portanto, não chamar qualquer save () métodos em seus modelos, nem emitem os sinais pre_save ou post_save (que são uma consequência de chamar Model.save ( )). Se você deseja atualizar um monte de registros para um modelo que tem um método save () personalizado, laço sobre eles e chamar save ()

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update

Respondeu 11/09/2018 em 09:19
fonte usuário

votos
-22

Os sinais são úteis quando você tem que executar algum processo a longo prazo e não deseja bloquear o usuário espera de salvar para completar.

Respondeu 25/03/2011 em 17:53
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more