-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to filter the queryset used by the widgets in a form collection? #164
Comments
I created a fork with my tests here: there is some fixture data to replicate the compant/team/department |
so it seems like I can modify the fieldset used by the widget during the form rendering by overriding get_context:
but I don't see anything in the ModelForm instance that gets passed from the View.... other than the initial object. So maybe pass some extra values in that...? |
I found myself with the same problem in my use case. I ended up writing these: class FormsetContextCollectionViewMixin:
def get_collection_kwargs(self):
kwargs = super().get_collection_kwargs()
kwargs["args"] = self.args
kwargs["kwargs"] = self.kwargs
kwargs["request"] = self.request
return kwargs
class ContextFormCollection(FormCollection):
def __init__(self, *args, **kwargs):
self.request_args = {}
self.request_args["request"] = kwargs.pop("request")
self.request_args["args"] = kwargs.pop("args")
self.request_args["kwargs"] = kwargs.pop("kwargs")
for name, holder in self.declared_holders.items():
self.update_holder_instances(name, holder)
super().__init__(*args, **kwargs)
def update_holder_instances(self, name, holder):
"""
Request args are available in the self.request_args dict. Implement form logic here
"""
pass And I use them like this: # views.py
class UserCollectionCreateView(FormsetContextCollectionViewMixin, EditCollectionView):
model = User
collection_class = UserCollection
template_name = "form-collection.html"
success_url = "/"
# forms.py
class UserForm(ModelForm):
class Meta:
model = User
fields = ["email", "username", "password"]
class ExtendUserForm(ModelForm):
class Meta:
model = ExtendUser
fields = ["phone_number"]
def model_to_dict(self, user):
try:
return model_to_dict(
user.extend_user, fields=self._meta.fields, exclude=self._meta.exclude
)
except ExtendUser.DoesNotExist:
return {}
def construct_instance(self, user):
try:
extend_user = user.extend_user
except ExtendUser.DoesNotExist:
extend_user = ExtendUser(user=user)
form = ExtendUserForm(data=self.cleaned_data, instance=extend_user)
if form.is_valid():
construct_instance(form, extend_user)
form.save()
class UserCollection(ContextFormCollection):
default_renderer = FormRenderer()
user = UserForm()
extend_user = ExtendUserForm()
def update_holder_instances(self, name, holder):
print({name: holder})
# the holder is the instanced form, you can either change it directly or call a method in it,
# and we have access to the views context from self.request_args |
Hi,
I am trying to use the form collections for a set of nested models and filter the queryset for relevant form widgets in the context of the correct "parent" foreign key object. For example using the testapp companies model, if I have a form collection view on some "Department" and department has a field "sales_team" to teams. Then I want to filter the options in the sales_team selection widget in the department form to only those teams in the same department.
To show what I mean, I have added a "sales_team" field to department, which points (nullably) to one of its own teams.
code
I tell the DepartmentForm about the queryset using the __init_method:
code
And that works to limit the available sales teams to only those owned by that department:
That is filtered from the full list of teams:
However when this is switched over to using form collections, it stops applying the filters. The problem I am having with form collections is that the modelForms for the collection are initialized during import, so I can't use the "init" method to set the querysets for the widgets.
Like, this Form is created at package import time, so the form can't easily be given any instance data at that time:
The collections form version is finding the "teams" for the department:
I've been digging about in the code looking for the correct method to override.... can anyone give me a pointer
The text was updated successfully, but these errors were encountered: