Con*_*ius 6 django django-signals django-models
我有以下型号:
class Item(models.Model):
# fields
# ...
class Collection(models.Model):
items = models.ManyToManyField(Item, related_name="collections")
# other fields
# ...
Run Code Online (Sandbox Code Playgroud)
现在我想要两件事:
Item可以添加到Collection.Collection如果Item添加或删除了一些字段,我希望更新它的一些字段.对于第二个问题,我知道django.db.models.signals.m2m_changed我可以使用它来挂钩关系的变化.允许/确定更改Collection信号回调内部吗?我是否也可以使用该信号"中止"问题1的插入?
我认为处理所需行为的最佳方法不是使用信号,而是使用表中的重写的save()和delete()方法through,您将使用参数显式定义,through请参阅:https://docs.djangoproject .com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.through.这个:https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods
像这样的东西:
# -*- coding: utf-8 -*-
from django.db import models
class Item(models.Model):
# fields
# ...
class Collection(models.Model):
items = models.ManyToManyField(Item, related_name="collections", through="CollectionItem")
# other fields
# ...
class CollectionItem(models.Model):
collection = models.ForeignKey(Collection)
item = models.ForeignKey(Item)
def save(self, *args, **kwargs):
# Only allow this relationship to be created on some_condition
# Part 1 of your question.
if some_condition:
super(CollectionItem, self).save(*args, **kwargs)
# Update some fields on Collection when this
# relationship is created
# Part 2 of your question (1/2)
self.Collection.updateSomeFields()
def delete(self, *args, **kwargs):
collection = self.collection
super(CollectionItem, self).delete(*args, **kwargs)
# Update some fields on Collection when this relationship
# is destroyed.
# Part 2 of your question (2/2)
collection.updateSomeFields()
Run Code Online (Sandbox Code Playgroud)
顺便提一下,你会发现添加一个关系会在这个模型上产生一个保存信号.
而且,关于信号,一旦你有了直通表,你就可以监听pre_save和/或post_save信号,但是它们都不允许你直接否决关系的创建.
如果您的一个或两个模型由第三方提供,而您实际上无法创建直通表,那么,是的,信号路径可能是唯一的出路.
https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
在这种情况下,您可以侦听m2m_changed事件并触发对集合对象的更新(问题的第2部分),并追溯删除不恰当创建的关系(问题的第1部分).然而,由于后一位是一个非常丑陋的kludgy,如果可以,我会坚持使用显式通过表.
| 归档时间: |
|
| 查看次数: |
2520 次 |
| 最近记录: |