Django Пользовательские формы в наборах форм с использованием CBV

Я хочу создать новый сайт и одновременно добавить соответствующие публикации. Мне приходится использовать специальную форму для "сайта" из-за большого набора данных, связанного с ним через внешний ключ "муниципалитет"

У меня есть эти модели:

class site(models.Model):
    sid = models.AutoField(primary_key=True)
    site_name = models.CharField(max_length=250)
    site_notes = models.CharField(max_length=2500, blank=True, null=True)
    municipality = models.ForeignKey('local_administrative_unit', on_delete=models.PROTECT)
    geom = models.PointField(srid=4326)

    def __str__(self):
        return '{}, {} ({})'.format(self.sid, self.site_name, self.municipality)

lass cit_site(models.Model):
    cit_site_id = models.AutoField(primary_key=True)
    publication = models.ForeignKey('publication', on_delete=models.PROTECT)
    site = models.ForeignKey('site', on_delete=models.PROTECT)
    first_page = models.IntegerField(null=True, blank=True)
    last_page = models.IntegerField(null=True, blank=True)
    notes = models.CharField(max_length=500, null=True, blank=True)

    def __str__(self):
        return '{}: {} - {}'.format(self.publication.pub_id, self.first_page, self.last_page)

На данный момент форма site просто добавляет site через представление на основе класса. Из-за большого набора данных муниципалитетов, загрузка формы заняла бы вечность и было бы не очень удобно выбирать нужный муниципалитет (16k+ записей в этой таблице на данный момент), поэтому я сделал эту пользовательскую форму:

class NewSiteForm(DynamicFormMixin, forms.Form):    
    
    def land_choices(form):
        country = form['country'].value()
        return models.administrative_level_4.objects.filter(adm_level_5=country)

    def land_initial(form):
        country = form['country'].value()
        return models.administrative_level_4.objects.filter(adm_level_5=country).first()

    def district_choices(form):
        land = form['land'].value()
        return models.administrative_level_3.objects.filter(adm_level_4=land)

    def district_inital(form):
        land = form['land'].value()
        return models.administrative_level_3.objects.filter(adm_level_4=land).first()

    def town_choices(form):
        district = form['district'].value()
        return models.administrative_level_2.objects.filter(adm_level_3=district)

    def town_initial(form):
        district = form['district'].value()
        return models.administrative_level_2.objects.filter(adm_level_3=district).first()

    def municipality_choices(form):
        town = form['town'].value()
        return models.local_administrative_unit.objects.filter(adm_level_2=town)

    def municipality_initial(form):
        town = form['town'].value()
        return models.local_administrative_unit.objects.filter(adm_level_2=town).first()


    country = forms.ModelChoiceField(
        queryset=models.administrative_level_5.objects.all(), empty_label='Select a country...'
    )
    land = DynamicField(
        forms.ModelChoiceField,
            queryset=land_choices,
            initial=land_initial                   
    )
    district = DynamicField(
        forms.ModelChoiceField,
            queryset=district_choices,
            initial=district_inital
    )
    town = DynamicField(
        forms.ModelChoiceField,
            queryset=town_choices,
            initial=town_initial
    )
    siteMunicipality = DynamicField(
        forms.ModelChoiceField,
            queryset=municipality_choices,
            initial=municipality_initial
    )
    siteNotes = forms.CharField(
        required=False,
        widget=forms.Textarea
        )

    siteName = forms.CharField()

В нем используется некоторое количество htmx для заполнения каскадных выпадающих элементов, что позволяет ему загружаться намного быстрее. Вид выглядит следующим образом:

class NewSiteView(FormMixin, View):
    form_class = forms.NewSiteForm
    template_name = 'datamanager/newsiteCascade.html'
    success_url = 'datamanager/newsiteCascade.html'
    
    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, {'form':form})

    def post(self, request, *args, **kwargs):
        
        form = self.get_form()
        if form.is_valid():
            pol = models.local_administrative_unit.objects.values('geom').filter(lau_id=form.cleaned_data['siteMunicipality'].lau_id)[0]['geom']
            cent_point = pol.centroid
            geom = cent_point.wkt
            municipality = form.cleaned_data['siteMunicipality']
            site_name = form.cleaned_data['siteName']
            site_notes = form.cleaned_data['siteNotes']

            new_site = models.site(site_name = site_name, site_notes=site_notes, municipality=municipality, geom=geom)
            new_site.save()

            if 'Save' in request.POST:
                return HttpResponseRedirect(reverse_lazy('data_manager:all_sites'))
            elif 'SaveAnother' in request.POST:
                return HttpResponseRedirect(reverse_lazy('data_manager:new_site'))

###############################################################
## HTMX Queries
###############################################################

def lands(request):
    form = forms.NewSiteForm(request.GET)
    return HttpResponse(form['land'])

def districts(request):
    form = forms.NewSiteForm(request.GET)
    return HttpResponse(form['district'])

def towns(request):
    form = forms.NewSiteForm(request.GET)
    return HttpResponse(form['town'])

def siteMunicipalities(request):
    form = forms.NewSiteForm(request.GET)
    return HttpResponse(form['siteMunicipality'])

Однако в настоящее время мне приходится добавлять литературу на эти сайты из другой формы (просто модельформы из модели cit_site, показанной выше) после создания сайта. Я хочу сделать все это за один раз, чтобы я мог создать site, добавить цитаты и сохранить все вместе. Я также хочу продолжать использовать каскадные выпадающие элементы из формы выше, чтобы избежать проблемы загрузки.

Насколько я понимаю, мне нужно использовать некий набор форм, который хранит обе формы. Но все, что я нашел до сих пор, использовало modelforms, что не было бы полезно в моем случае (нет пользовательской формы). Кроме того, данные для родительской формы, похоже, уже должны существовать при отображении набора форм. Поэтому мне нужна помощь в решении этой проблемы (возможно, это две проблемы в одной?). Заранее спасибо.

Вернуться на верх