Django manytomany field in admin - 如何添加默认列表



我想在 manytomany 字段中添加一个默认的项目列表,以防在 admin 中更新时将其留空。

我的问题是,通过覆盖 save、save_model 或 post_save 信号来更改多对多字段不起作用,因为 django 还没有完成保存子关系,只有父级(例如。Django:多对多关系的自定义保存方法)。 我尝试了信号m2m_changed,这是其他帖子中建议的解决方案,不会被触发,因为如果列表留空,它就不会改变!

谁能想到另一种方法,因为我似乎已经到达了方法覆盖和信号的死胡同? 我不介意在管理员中显示表单之前还是之后添加默认列表。

更新

什么不起作用:

(夹具是我的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!"

您可以覆盖管理表单,并在 ManyToMany 字段的表单清理方法中实现逻辑。例如。

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

这是我用来在管理员表单集中自动填充作者(如果未设置)的代码片段

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)

最新更新