Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Django admin时未保存多个字段_Python_Django_M2m_Django Orm - Fatal编程技术网

Python 使用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 =

我遇到了一个奇怪的问题,我希望这里的人能解释一下

我正在重写模型的save()方法,以便在运行super()之后向多个字段添加一些值。我的问题是,当我在Django admin中保存时,这些值似乎被添加到关系中,但随后又变为空

但是,如果我从
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表单重写了所有记录

这就是为什么一步一步地:

  • 主对象已更新

  • 您的代码(在保存方法或信号中)进行了更改(您可以 查看它们,只需在ModelAdmin中设置一个断点即可:

  • save_m2m()接受页面上的所有m2m值(粗略地说),并通过相关管理器替换所有m2m记录。这就是为什么在事务结束时看不到更改的原因
  • 有一个解决方案:通过m2m进行更改 事务。正在提交。transaction.on\u commit将进行更改 提交事务时,在form.save_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)