Python 使用Django admin时未保存多个字段
我遇到了一个奇怪的问题,我希望这里的人能解释一下 我正在重写模型的save()方法,以便在运行super()之后向多个字段添加一些值。我的问题是,当我在Django admin中保存时,这些值似乎被添加到关系中,但随后又变为空 但是,如果我从Python 使用Django admin时未保存多个字段,python,django,m2m,django-orm,Python,Django,M2m,Django Orm,我遇到了一个奇怪的问题,我希望这里的人能解释一下 我正在重写模型的save()方法,以便在运行super()之后向多个字段添加一些值。我的问题是,当我在Django admin中保存时,这些值似乎被添加到关系中,但随后又变为空 但是,如果我从manage.py shell执行此操作,它将正常工作 我在其中放了两个print语句,它们产生完全相同的输出,不管我是通过Django admin还是通过shell运行它 class Store(models.Model): holidays =
manage.py shell
执行此操作,它将正常工作
我在其中放了两个print语句,它们产生完全相同的输出,不管我是通过Django admin还是通过shell运行它
class Store(models.Model):
holidays = models.ManyToManyField(StoreHoliday, blank=True)
copy_holidays_from = models.ForeignKey('Store', blank=True, null=True)
def save(self):
print '==== BEFORE SAVE:', self.holidays.all()
super(Store, self).save()
self.copy_holidays()
print '==== AFTER SAVE:', self.holidays.all()
def copy_holidays(self):
if self.pk and self.copy_holidays_from:
self.holidays.clear()
for h in self.copy_holidays_from.holidays.all():
self.holidays.add( h )
这是print
语句的输出:
==== BEFORE SAVE: []
==== AFTER SAVE: [<StoreHoliday: 10 Mar 2010, Chuck Norris birthday (Closed)>]
==保存前:[]
==保存后:[]
有人对可能导致这种情况的原因有什么建议吗
编辑:通过管理界面保存时,Django似乎会放弃对save()中m2m关系的所有手动更改。这与它处理表单的方式有关吗?因此,上面的方法不是实现表单的正确方法。代码通过重写模型_save()而属于StoreAdmin 我就是这样解决的:
class StoreAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if obj.copy_holidays_from:
form.cleaned_data['holidays'] = obj.copy_holidays_from.holidays.all()
super(StoreAdmin, self).save_model(request, obj, form, change)
我可能在今天遇到了同样的行为,是的,你认为这与django处理数据的方式有关是正确的 django管理员分别对多个字段和实际对象进行更改。(请记住,m2m保存在不同的数据库表中) 在我的例子中,如果我没有在管理站点的ManyToMany字段中选择任何内容,这将转换为对ManyToMany关系的clear()-操作。您在save()-方法中执行的所有操作都会立即被清除。我在post_save信号处理程序中也做了同样的事情
解决方案(对我来说)是将多个字段分隔成一个内联字段,这样在修改对象时它不会自动保存为空。对我来说,问题是管理员只保存多个字段中最后选择的实例(上次选择的“假日”)。因此,我必须重写save_model方法,如下所示:
@admin.register(Store)
class StoreAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
form.cleaned_data['holidays'] = StoreHoliday.objects.filter(pk__in=dict(request.POST).get('holidays'))
super(StoreAdmin, self).save_model(request, obj, form, change)
我花了很多时间在上面,其他解决方案都不起作用,所以我希望它能有所帮助。在django 2,1,4中,我的解决方案是使用save_related()
更新m2m的解决方案之一,同时更新您的一个型号
Django 1.11及更高版本
在更新过程中,当您对m2m记录所做的更改未保存时,即使在您的模型或信号中的保存方法中进行了更改,您可以观察到的行为仅发生在主对象更新后,因为m2m表单重写了所有记录
这就是为什么一步一步地:
不幸的是,此解决方案的缺点是,您对m2m的更改将在单独的事务中执行。我不知道您的问题出在哪里,但是
self.holidays=self.copy\u holidays\u from.holidays.all()
看起来比清除和迭代好得多。谢谢您的提示,我不知道这是可能的。你可以在下面看到我做错了什么。你好,Jyrsa,我和Django管理员有类似的问题。我们有一个m2m字段,当保存页面的其余部分时,该字段有时会被清除。我不知道Django单独保存它。你能给我链接一些关于m2m是如何处理的更多信息吗?能否更具体地说明在什么情况下清除save方法的操作?非常感谢。
def save_related(self, request, form, formsets, change):
super().save_related(request, form, formsets, change)
form.instance.permissions.add(request.user)
def save_related(self, request, form, formsets, change):
breakpoint()
form.save_m2m()
for formset in formsets:
self.save_formset(request, form, formset, change=change)