Django:ModelForm的kwargs使用及关联Event主键获取问题
Hey, let's work through this problem together. Since you've disabled adding new registrations with has_add_permission(self, request): return False, all your inline forms are tied to existing Registration objects—which simplifies things a lot, because each of those registrations is already linked to an Event via a foreign key.
Quick Fix for Your Current Setup
In your RegistrationForm's __init__ method, you can directly access the linked Event through the form's instance attribute. Here's how to implement it:
def __init__(self, *args, **kwargs): # Always call the parent __init__ first super().__init__(*args,** kwargs) # Get the existing Registration instance registration_instance = self.instance # Traverse the foreign key to get the associated Event self.event = registration_instance.event # Grab the Event's primary key self.event_pk = self.event.pk # Now you can use self.event_pk for your custom logic # Example: Filter a dropdown based on the Event # self.fields['attendee'].queryset = Attendee.objects.filter(event=self.event)
This works because when the admin loads the inline form for an existing Registration, self.instance refers to that specific registration object. You can just follow its foreign key relationship to get the connected Event and its PK.
If You Ever Enable New Registrations
If you later decide to allow adding new Registration entries, the above method won't work for unbound (new) forms. For that scenario, you can pass the parent Event instance from the inline to the form by overriding get_formset in your RegistrationInline:
First, update your RegistrationForm to accept an optional event parameter:
class RegistrationForm(forms.ModelForm): def __init__(self, *args, event=None, **kwargs): super().__init__(*args,** kwargs) self.event = event if self.event: self.event_pk = self.event.pk # Add your custom logic here using the Event PK class Meta: model = Registration fields = ['your_registration_fields_here']
Then, modify your RegistrationInline to inject the parent Event into the form:
class RegistrationInline(admin.StackedInline): model = Registration form = RegistrationForm def has_add_permission(self, request): return False # Adjust this to True if you want to allow new entries def get_formset(self, request, obj=None, **kwargs): # `obj` is the parent Event instance being edited in the admin formset = super().get_formset(request, obj,** kwargs) # Wrap the form to pass the event parameter original_form = formset.form def wrapped_form(*args, **wrapper_kwargs): return original_form(*args, event=obj, **wrapper_kwargs) formset.form = wrapped_form return formset
This ensures that even new forms in the inline have access to the parent Event instance and its PK.
内容的提问来源于stack exchange,提问作者Aliquis

