在我的django管理员中,我正在创建一个与另一个表有一对多关系的管理模型。我们称之为Recipes
和Ingredients
。每种配方都有多种成分。
我想在管理页面中这样做,用户可以创建配方并在同一页面上添加某些成分。所以我使用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
。这也开始变得相当复杂,所以我想知道是否有更好的方法来检查发布内联成分的权限并正确保存该列。
答案 0 :(得分:-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()