Django模型覆盖保存功能不更新db中的m2m字段

时间:2014-04-17 07:58:47

标签: python django model

当我从管理面板添加新横幅时,我想要在创建时与横幅相关联的关键字不会添加到数据库中。

class Banners(models.Model):
    objects = BannerManager()
    banner_location = models.ManyToManyField(BannerLocation, verbose_name=_("Banner's Location"), default=None, null=True, blank=True)
    keywords = models.ManyToManyField(Keywords, verbose_name=_("Banner's Related Keywords"), null=True, blank=True)
    width = models.IntegerField(verbose_name=_("Banner Width"), null=False, blank=False)
    height = models.IntegerField(verbose_name=_("Banner Height"), null=False, blank=False)
    invocation_code = models.TextField(verbose_name=_("Banner Height"), null=False, blank=False)
    is_enable = models.BooleanField(verbose_name=_("Is Enable"), default=False)
    banner_updated = models.DateTimeField(auto_now=True)
    banner_created = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = "Banner"
        verbose_name_plural = "Banners"
        ordering = ['-banner_updated', 'is_enable']

    def __unicode__(self):
        return "width: %s, height: %s" % (self.width, self.height)

    def save(self):
        is_new = False
        if self.pk is None:
            is_new = True
        super(Banners, self).save()
        if is_new == True:
            keyword = Keywords.objects.get(pk=1)
            self.keywords.add(keyword)

1 个答案:

答案 0 :(得分:1)

如果管理员表单中有keywords字段,则会发生以下情况:

  1. 您在管理员的新Banners实例上按了保存(未选择关键字)
  2. Django admin model-form保存Banners实例
  3. 您的被覆盖的save方法会添加您的关键字
  4. Django admin将关键字m2m字段设置为表单中提交的任何关键字(替换您在保存方法中设置的内容)
  5. Django这样做的原因是,正如您所知,在添加m2m关系之前必须保存Banners实例。

    我过去常常在这里弄乱m2m_changed信号......但是你很可能最终只能在Django管理网站中的一些情况下工作,但在其他代码中没有意义。

    我认为你的保存方法正常工作(在Django管理员之外的控制台中试用),你真正需要的是自定义管理表单的行为:

    class BannersForm(forms.ModelForm):
        class Meta:
            model = Banners
    
        def __init__(self, *args, **kwargs):
            if kwargs.get('instance') is None:
                # create new Banners
                initial = kwargs.get('initial', {})
                initial.update({'keywords': Keywords.objects.filter(pk=1)})
                kwargs['initial'] = initial
            super(BannersForm, self).__init__(*args, **kwargs)
    
    
    class BannersAdmin(admin.ModelAdmin):
        form = BannersForm
    
    
    admin.site.register(Banners, BannersAdmin)