使用Django,我遇到了“多对多”字段的已知问题。在post_save_event信号/挂钩中,“事件”实例中“多对多”字段的值:类别不会使用管理表单上提交的最新值进行更新。它始终显示旧值。
这是我的保存钩子,其中有一个父级“事件”,每个事件都有一个0或多个类别的字段。但是,instance.categories值不会更新为最新值。
@receiver(post_save, sender=Event)
def post_save_event(sender, instance, **kwargs):
success = events_api.create_or_update_event(instance)
我知道为什么会这样。基本上,多对多字段需要保存在父模型之后,因为多对多表需要具有事件的主键。
我做了下面在网上找到的修复程序。这是在执行多对多表事务之后发送的信号。
这种工作方式可以解决,但是很明显,这意味着如果事件中的类别发生更改,则api将被多次调用,更糟糕的是,发生m2m_changed信号似乎会触发两次。所以我最终一次调用了3次api。
任何解决方法/挂钩我都可以用来成功保存表单而不是post_save事件吗?
def category_has_changed(sender, **kwargs):
logger.error("Inside: Inside category has changed")
instance = kwargs.pop('instance')
success = events_api.create_or_update_event(instance)
m2m_changed.connect(category_has_changed, sender=Event.categories.through)
events_api的相关部分:
def _create_or_update_event(event, mode):
response = None
try:
headers = get_api_headers(event.cms_event_id)
categories = []
for cat in event.categories.all():
categories.append(cat.id)
# ISSUE: event.categories.all() does not contain the most recent updated array of categories
# Basic event details.
body = {
'cms_event_id': str(event.cms_event_id),
'categories': categories,
}
requests.post(ENDPOINT_CREATE_EVENT, json=body, headers=headers)
型号:
class Category(models.Model):
name_en = models.CharField(
_('Category name (English)'),
blank=True, null=True, max_length=200,
help_text=_('''
Helpful details (for English language customers) about where the workshop is taking
place, such as the location inside the store (ex. 2nd floor cafeteria).
'''))
name_fr = models.CharField(
_('Category name (French)'),
blank=True, null=True, max_length=200,
help_text=_('''
Helpful details (for English language customers) about where the workshop is taking
place, such as the location inside the store (ex. 2nd floor cafeteria).
'''))
def __str__(self):
return self.name_en
class Meta:
ordering = ('name_en',)
verbose_name_plural = _('Categories')
class Event(Page):
formfield_overrides = {
models.ManyToManyField: {'widget': CheckboxSelectMultiple},
}
super_manager = models.Manager()
...
categories = models.ManyToManyField(blank=True, null=True, to='Category')
答案 0 :(得分:0)
我能够像这样
在我的modelAdmin中修改save_modelclass EventAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.new_categories = form.cleaned_data.get('categories')
obj.save()
super().save_model(request, obj, form, change)
然后在signals.py中将它作为实例的一部分:
instance.new_category