I am trying to implement an inline form for the Product model in the admin interface. In addition to displaying forms for existing ProductAttribute relationships, I want to automatically add forms for all attributes associated with the category of the product being edited. However, the problem is that, although the forms are displayed correctly, saving the form does not create a new ProductAttribute relationship in the database, and the cleaned_data for these forms is empty.
admin.py:
...
class ProductAttributeInline(admin.TabularInline):
model = ProductAttribute
formset = ProductAttributeInlineFormset
fields = ('attribute', 'value')
readonly_fields = ('attribute',)
def has_add_permission(self, request, obj=None):
return False
u/admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = (
'name',
'category',
'price',
'sku',
'created_at',
'updated_at'
)
search_fields = ('name', 'sku')
list_filter = ('category',)
inlines = (ProductAttributeInline,)
...
forms.py:
from django import forms
from .models import ProductAttribute
class ProductAttributeInlineFormset(forms.models.BaseInlineFormSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance and self.instance.pk:
category = self.instance.category
if category:
attributes = category.attributes.all()
existing_attributes = set(
self.queryset.values_list('attribute', flat=True)
)
extra_forms_count = 0
for attribute in attributes:
if attribute.id not in existing_attributes:
form = self._construct_form(
len(self.forms),
instance=ProductAttribute(
product=self.instance,
attribute=attribute,
),
)
self.forms.append(form)
extra_forms_count += 1
self.extra = extra_forms_count