These are my models:
class Template(models.Model):
class Pages(models.IntegerChoices):
COVER = 0, "COVER"
FIRST = 1, "FIRST"
AFTERFIRST = 2, "BEFORETABLE"
BEFORELAST = 3, "AFTERTABLE"
LAST = 4, "LAST"
name = models.CharField("name", max_length=128)
page = models.PositiveIntegerField(choices=Pages.choices)
text = models.TextField("html allowed", blank=True, null=True)
class Inquiry(models.Model):
name = models.CharField(max_length=64)
templates = models.ManyToManyField(Template, through="InquiryTemplate")
class InquiryTemplate(models.Model):
inquiry = models.ForeignKey(Inquiry, on_delete=models.CASCADE)
template = models.ForeignKey(Template, on_delete=models.CASCADE)
class Meta:
unique_together = ("inquiry", "template")
def __str__(self):
return f"{self.template.get_page_display()}"
and this is the admin:
class InquiryTemplateInlineForm(forms.ModelForm):
cover_template = forms.ModelChoiceField(queryset=Template.objects.filter(page=Template.Pages.COVER), required=False, label="Cover Template")
first_template = forms.ModelChoiceField(queryset=Template.objects.filter(page=Template.Pages.FIRST), required=False, label="First Template")
beforetable_template = forms.ModelChoiceField(queryset=Template.objects.filter(page=Template.Pages.BEFORELAST), required=False, label="Before Table Template")
aftertable_template = forms.ModelChoiceField(queryset=Template.objects.filter(page=Template.Pages.AFTERFIRST), required=False, label="After Table Template")
last_template = forms.ModelChoiceField(queryset=Template.objects.filter(page=Template.Pages.LAST), required=False, label="Last Template")
class Meta:
model = InquiryTemplate
fields = ["cover_template", "first_template", "beforetable_template", "aftertable_template", "last_template"]
def __init__(self, *args, **kwargs):
inquiry = kwargs.pop("inquiry", None)
super().__init__(*args, **kwargs)
if inquiry:
existing_templates = InquiryTemplate.objects.filter(inquiry=inquiry)
for template in existing_templates:
if template.template.page == Template.Pages.COVER:
self.initial["cover_template"] = template.template
elif template.template.page == Template.Pages.FIRST:
self.initial["first_template"] = template.template
elif template.template.page == Template.Pages.BEFORELAST:
self.initial["beforetable_template"] = template.template
elif template.template.page == Template.Pages.AFTERFIRST:
self.initial["aftertable_template"] = template.template
elif template.template.page == Template.Pages.LAST:
self.initial["last_template"] = template.template
class InquiryTemplateInline(admin.TabularInline):
model = InquiryTemplate
form = InquiryTemplateInlineForm
extra = 0
def get_formset(self, request, obj=None, **kwargs):
formset = super().get_formset(request, obj, **kwargs)
formset.inquiry = obj
return formset
class InquiryAdmin(admin.ModelAdmin):
inlines = [InquiryPartInline, InquiryTemplateInline]
def save_formset(self, request, form, formset, change):
super().save_formset(request, form, formset, change)
InquiryTemplate.objects.filter(inquiry=form.instance).delete()
if formset.cleaned_data[0].get("cover_template"):
InquiryTemplate.objects.create(inquiry=form.instance, template=cover_template)
if formset.cleaned_data[0].get("first_template"):
InquiryTemplate.objects.create(inquiry=form.instance, template=first_template)
if formset.cleaned_data[0].get("beforetable_template"):
InquiryTemplate.objects.create(inquiry=form.instance, template=beforetable_template)
if formset.cleaned_data[0].get("aftertable_template"):
InquiryTemplate.objects.create(inquiry=form.instance, template=aftertable_template)
if formset.cleaned_data[0].get("last_template"):
InquiryTemplate.objects.create(inquiry=form.instance, template=last_template)
This looks like this:
which is exactly what I want from the functional point of view. But:
- I thought when I override the
get_formset()
method of theTabularInline
I could use myInquiry
instance in theInquiryTemplateInlineForm
to prepopulate it with values, butinquiry
isNone
here - When i set for example 4 templates and click save → I get 4 rows of templates on reload.