管理员中的Django manytomany字段 - 如何添加默认列表?

时间:2013-09-10 17:32:58

标签: django django-admin

我想在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!"

2 个答案:

答案 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)