Pergunta

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

 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 de usar despachante sinal de Django?

Foi útil?

Solução

Salvar / sinais de exclusão são geralmente favoráveis ??em situações onde você precisa 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 em métodos save substituídos é 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 sinal pre_save, 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 sinal pre_save para gerir um conjunto de campos que descrevem uma estrutura de árvore para o modelo que está prestes a ser criado ou atualizado eo sinal pre_delete para remover detalhes estrutura de árvore para o objeto que está sendo excluído e seu toda a 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 métodos save ou delete 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.

Outras dicas

Você perguntou:

haveria nenhum benefício ao uso de despachante sinal de Django?

Eu encontrei este na documentação do Django:

métodos modelo sobrescritas não são chamados em operações em massa

Note que o método delete () para um objeto não é necessariamente chamado quando a eliminação de objectos em massa usando um QuerySet ou como um resultado de um cascata delete. 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 grandes quantidades, desde que nenhum de save (), pre_save, e são post_save chamado.

De: Overriding predefinido métodos modelo

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 é coisa muito model-relacionado.

É uma espécie tipo de desnormalização. Olhe para este muito solução . No local definição de campo composição.

Pequenas além de docs Django sobre exclusão em massa (método .delete() em objetos QuerySet):

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

https://docs.djangoproject.com/ en / 1,11 / temas / db / consultas / # apagando-objetos

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

Finalmente, perceber que update () faz uma atualização no nível do SQL e, Assim, 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 chamando Model.save ()). Se você deseja atualizar um monte de registros para um modelo que tem um costume save () método, loop sobre eles e chamar save ()

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top