我想在manytomany字段中添加一个默认的项目列表,如果在admin中更新时它是空白的。
我的问题是通过覆盖save,save_model或post_save信号来改变manytomany字段不起作用,因为django尚未完成保存子关系,只有父关系(例如Django: Custom Save method for Many-to-Many relation)。我尝试了信号m2m_changed,在其他帖子中建议的解决方案,不会被触发,因为如果列表留空,它将不会改变!
任何人都可以想到另一种方法,因为我似乎已经通过方法覆盖和信号达到了死胡同?我不介意在管理员显示表单之前或之后添加默认列表。
更新
什么行不通:
(Fixtures是我的m2m字段的名称)。
我已经尝试了以下建议,覆盖了各种方法。 通过此跟踪,您可以看到已添加并通过管理员和模型的许多方法可见的夹具,但在调用这些方法后,它们将被删除并替换。似乎没有可以覆盖的after_everything_else方法。
[Wed Sep 18 15:24:06 2013] [error] in save of model fixture count = 0
[Wed Sep 18 15:24:06 2013] [error] in save of overriden admin model form fixture count = 15
[Wed Sep 18 15:24:06 2013] [error] in save_model of admin fixture count = 15
[Wed Sep 18 15:24:06 2013] [error] in save of model fixture count = 15
做了什么
覆盖管理表单并将clean_fixtures方法放在那里。 clean_fixtures不会被调用,它只是放在管理资源中,它必须是一个覆盖的形式,如下所示:
class RankingUpdateForm(forms.ModelForm):
def clean_fixtures(self):
data = self.cleaned_data['fixtures']
# add default set of fixtures if none already there
if len(data) == 0:
return get_default_fixtures()
else:
return data
class RankingUpdateAdmin(admin.ModelAdmin):
list_display = ('rank_type','date', 'comment', 'issued')
form = RankingUpdateForm
def clean_fixtures(self):
assert False, "I'm never called!"
def save_formset(self):
assert False, "I'm never called either!"
答案 0 :(得分:1)
您可以覆盖Admin Form并在ManyToMany字段的表单clean方法中实现逻辑。例如。
def clean_recipients(self):
data = self.cleaned_data['recipients']
if not data:
# return default recipients if the selected list is empty.
data = [r.pk for r in Recipient.objets.all()] #just an example, you can alter this query to select your defaults
return data
覆盖保存方法以保存接收器
def save(self, commit=True):
instance = forms.ModelForm.save(self, False)
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
instance.recepient_set.clear()
for recepient in self.cleaned_data['recepients']:
instance.recepient_set.add(recepient)
self.save_m2m = save_m2m
if commit:
instance.save()
self.save_m2m()
return instance
答案 1 :(得分:0)
这是我用来在管理表格中自动填充作者的代码片段(如果未设置)
class AutoAuthoredModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if obj.author is None:
obj.author = request.user
super(AutoAuthoredModelAdmin, self).save_model(request, obj, form, change)
def save_formset(self, request, form, formset, change):
if hasattr(formset.model, 'author'):
instances = formset.save(commit=False)
for instance in instances:
if instance.author is None:
instance.author = request.user
super(AutoAuthoredModelAdmin, self).save_formset(request, form, formset, change)