Django模型覆盖保存功能,不更新db中的m2m字段 [英] Django model override save function not updating m2m field in db
问题描述
当我从管理面板中添加一个新的横幅时,我想在其创建时关联横幅的关键字不会添加到db中。
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 Keyword),null = True,blank = True)
width = models.IntegerField(verbose_name = _ (横幅宽度),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):
returnwidth:%s,height:%s%(self.width,self.height)
def save(self):
is_new = False
如果self.pk为无:
is_new = True
超级(横幅,自身).save()
如果is_new == True:
keyword =关键字.objects.get(pk = 1)
self.keywords.add(关键字)
如果您的管理员表格中有关键字
字段,则会发生什么:
- 您按保存在您的新的
横幅
实例在管理员(没有选择关键字) - Django admin model-form保存
横幅
实例 - 您被覆盖的
保存
方法添加你的keyw ords - Django管理员将关键字m2m字段设置为表单中提交的任何关键字(替换您在保存方法中设置的内容)
Django执行此操作的原因是因为您知道,必须先保存横幅
实例,然后才能添加m2m关系。 / p>
我过去一直在圆圈,自己在过去搞乱了$ code> m2m_changed 信号等等,可能最终只能在Django管理员网站的狭窄环境中工作,但在其他代码中没有任何意义。
您的保存方法是工作我认为(在Django管理员外部的控制台中尝试),您真正需要的是自定义管理表单的行为:
class BannersForm(forms.ModelForm):
class Meta:
model =横幅
def __init __(self,* args,** kwargs):
if kwargs.get('instance')为无:
#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(横幅,BannersAdmin)
When I add a new Banner from admin panel the keyword I want to associate with the banner at its creation does not get added in db.
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)
If you have the keywords
field in your admin form what happens is this:
- you press save on your new
Banners
instance in the admin (with no keywords selected) - Django admin model-form saves the
Banners
instance - your overridden
save
method adds your keywords - Django admin sets the keywords m2m field to whatever keywords were submitted in the form (replacing what you set in the save method)
The reason Django does this is because, as you know, the Banners
instance has to be saved before m2m relations can be added.
I have been round in circles with this myself in the past messing with m2m_changed
signal etc... but you're likely to end up with something that only works in narrow set of circumstances in the Django admin site, but doesn't make sense in other code.
Your save method is working I think (try it in a console, outside Django admin), what you really need is to customise behaviour of the admin form:
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)
这篇关于Django模型覆盖保存功能,不更新db中的m2m字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!