'django Form, MultipleChoiceField and circular import

I try to setup a ModelForm Formset - with Checkbox fields...

But if I set a queryset for my MultipleChoiceField I get an "ImportError"

ImportError: cannot import name 'Event' from partially initialized module 'ferienspiel.event.models' (most likely due to a circular import)

How can I make a queryset for my MultipleChoiceField-Fields in `forms.py? to avoid a circular import Error?

This self.fields["event"].queryset = Event.objects.all() is the reason for the ImportError. How can I populate my Checkboxes with Events-data with an other way?

My setup:

- app
--- model.py (contains Model and Formhandler, for Wagtail Page `def serve()` )
--- form.py (formset setup)
--- ulrs.py
--- views.py

forms.py

class ChildForm(ModelForm):

    def __init__(self, *args, **kwargs):

        super(ChildForm, self).__init__(*args, **kwargs)

        self.fields["event"].widget = CheckboxSelectMultiple()
        self.fields["event"].queryset = Event.objects.all().order_by("date", "time")

    class Meta:
        model = Child
        fields = ("first_name", "last_name", "date_of_birth", "text")
        widgets = {
       ...
       ...

model.py

class Event(Page):
    location = models.TextField(max_length=500, null=False)
    date = models.DateField(null=False)
    time = models.TimeField(null=False)


class EventRegistrationPage(Page):
    intro = models.TextField(blank=True)

    def serve(self, request):
        if request.method == "POST":
            parent_form = ParentForm(request.POST, request.FILES)
            childs_form = ChildFormSet(request.POST, request.FILES)

            if all([parent_form.is_valid(), childs_form.is_valid()]):
                for child in childs_form:
                    # print(f"child {child.cleaned_data}")
                    if child.is_valid():
                        new_child = child.save(commit=False)
                        new_child.parent = new_parent
                        new_child.save()
                        new_child.event.set(
                            child.cleaned_data.get("event")
                        )
                        child.save_m2m()
                        childs_data.append(new_child)


Solution 1:[1]

Basically, circular imports are the result of bad designs, you should find a better method, but if you want to stick with this, you can do it like so:-

from . import forms # if the form is not in same app change . to the app_name

parent_form = forms.ParentForm(request.POST, request.FILES)
childs_form = forms.ChildFormSet(request.POST, request.FILES)

forms.py

from . import models

self.fields["event"].queryset = models.Event.objects.all().order_by("date", "time")

This should resolve the circular import

Solution 2:[2]

Move the import line that imports the forms module into the body of the serve method. That way, it only has to import that module when running the serve method, rather than at startup:

class EventRegistrationPage(Page):
    intro = models.TextField(blank=True)

    def serve(self, request):
        from ferienspiel.events.forms import ParentForm, ChildFormSet

        if request.method == "POST":
            parent_form = ParentForm(request.POST, request.FILES)
            childs_form = ChildFormSet(request.POST, request.FILES)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 gasman