0

如果在管理员中更新时将其留空,我想在 manytomany 字段中添加默认的项目列表。

我的问题是通过覆盖 save、save_model 或 post_save 信号来更改 manytomany 字段不起作用,因为 django 尚未完成保存子关系,只有父关系(例如Django: Custom Save method for Many-to-Many关系)。我尝试了信号m2m_changed,其他帖子中建议的解决方案,不会被触发,因为如果列表留空,它就不会改变!

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

更新

什么不起作用:

(Fixtures 是我的 m2m 字段的名称)。

我已经尝试了以下建议,覆盖了各种方法。从这个trace你可以看到fixtures已经被添加并且可以通过admin和model的许多方法看到,但是在调用这些方法之后它们会被删除和替换。似乎没有可以覆盖的 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!"
4

2 回答 2

1

您可以覆盖管理表单并为您的 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
于 2013-09-10T19:09:01.757 回答
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)
于 2013-09-10T19:16:48.377 回答