0

在我的 django 管理员中,我正在创建一个与另一个表具有一对多关系的管理模型。让我们称之为RecipesIngredients。每个食谱都有多种成分。

我想让它在管理页面中,用户可以创建一个食谱并在同一页面上添加某些成分。所以我使用inline models. 问题是一旦创建了某些成分,就应该只允许编辑几个字段。所以我创建了两个独立的内联模型——一个用于编辑,一个用于添加。

另一个问题是,只有在用户具有特定权限的情况下才能创建成分。如果用户没有这些权限,它仍然会创建成分,但它们不是published。他们后来必须得到具有正确权限的人的批准。现在,我正在重写formset用于创建成分的内容。它看起来像这样:

class AddIngredientInlineFormset(forms.models.BaseInlineFormSet):
    model = Ingredient

    def save(self, commit=True):
        can_publish = self.request.user.has_perm('meals.publish_ingredient')
        for form in self.forms:
            if form.cleaned_data:
                Ingredient.objects.create(
                     is_published = can_publish, **kwargs
                )

class AddIngredientInline(admin.StackedInline):
    model = Ingredient
    formset = AddIngredientInlineFormset
    fields = ['name', 'amount', 'description']
    extra = 1

    def has_change_permission(self, request):
        return False

然后我有一个单独的内联类进行编辑:

class EditIngredientInline(admin.StackedInline):
    model = Ingredient
    fields = ['name', 'amount', 'description']
    readonly_fields = ['name', 'amount']
    extra = 0
    can_delete = False

    def has_add_permission(self, request):
        return False

然后在我的食谱管理模型中,它看起来像这样:

class RecipeAdmin(BaseModelAdmin):

    model = models.Recipe
    list_display = ['name']

    def add_view(self, request, form_url='', extra_context={}):
        self.inlines = [AddIngredientInline]
        return super(BaseModelAdmin, self).add_view(request, form_url, extra_context)

    def change_view(self, request, object_id, form_url='', extra_context={}):
        self.inlines = [EditIngredientInline, AddIngredientInline]
        return super(BaseModelAdmin, self).change_view(request, object_id, form_url, extra_context)

这适用于为这些食谱添加食谱和成分,并且显示对所有内容都很好。但是,当我尝试编辑给定食谱的现有成分时,我收到错误:IngredientFormFormSet' object has no attribute 'new_objects'

我想这是因为我没有formset.save()使用AddIngredientFormSet. 这也开始变得相当复杂,所以我想知道是否有更好的方法来检查发布内联成分的权限并正确保存该列。

4

1 回答 1

-1

我通过这样做解决了这个问题:

class AddIngredientInlineFormset(forms.models.BaseInlineFormSet):
    model = Ingredient

    def save(self, commit=True):
        can_publish =    self.request.user.has_perm('meals.publish_ingredient')
        # use commit = false so it doesn't do a hard save since not all
        # the fields are present in the form.
        instances = super(AddIngredientInlineFormSet, self).save(commit=False)
        for instance in instances:
            instance.random_variable = default_value
            instance.save()
于 2015-04-07T00:34:01.253 回答