Django Passing Custom Form Parameters to Formset

Django Passing Custom Form Parameters to Formset

I would use functools.partial and functools.wraps:

from functools import partial, wraps
from django.forms.formsets import formset_factory

ServiceFormSet = formset_factory(wraps(ServiceForm)(partial(ServiceForm, affiliate=request.affiliate)), extra=3)

I think this is the cleanest approach, and doesn't affect ServiceForm in any way (i.e. by making it difficult to subclass).

Django Passing Custom Form Parameters to ModelFormset

I think you want to make some changes to your custom factory function. It should return the formset class, not the form. How about this:

def make_vote_formset(game_obj, extra=0):
class _VoteForm(forms.ModelForm):
score = forms.ModelChoiceField(
queryset=Odds.objects.filter(game=game_obj),
widget=forms.RadioSelect(),
empty_label=None)

class Meta:
model = Vote
exclude = ['user',]
return modelformset_factory(Vote, form=_VoteForm, extra=extra)

Then in your view code:

current_game = Game.objects.filter(id=current_game_id)
VoteFormSet = make_vote_formset(current_game)
formset = VoteFormSet(
request.POST,
queryset=Vote.objects.filter(game__round=round, user=user))

Passing Custom Form parameter to formset

Digging through django.forms.models you can see that inlineformset_factory needs a form class, not an instance. This is why your last try works and the other fail...passing in an instance won't work.

This should give you what you are looking for:

class MyReadOnlyForm(MyForm):

def __init__(self, *args, **kwargs):
super(MyReadOnlyForm,self).__init__(readOnly=True, *args,**kwargs)

Formset = inlineformset_factory(ModelA, ModelB form=MyReadOnlyForm)

If you need both versions

if read_only is True:
form_class = MyReadOnlyForm
else:
form_class = MyForm

Formset = inlineformset_factory(ModelA, ModelB form=form_class)

Django - Passing Custom Form Parameters to modelfactory

Django 1.9 added a form_kwargs arguement so you should be able to do:

ContactPhoneFormSet = modelformset_factory(
ContactPhone, ContactPhoneForm, extra=1, can_delete=True)
formset = ContactPhoneFormSet(form_kwargs={'contact_id': contact_id})

Django Formset: Passing a parameter in each form instance

First, make sure that you do not include the user in the form:

HourFormSet = modelformset_factory(Hour, extra=5, exclude=('user',))

Then, add the user before saving the instances:

if request.method == 'POST':
formset = HourFormSet(request.POST)

if formset.is_valid():
instances = formset.save(commit=False) # This will return unsaved Hour objects
for instance in instances:
instance.user = request.user # Add the logged in user
instance.save()
return index(request)

formset = HourFormSet(queryset=Hour.objects.none())
context_dict = {'formset': formset}
return render_to_response('add_hours.html', context_dict, context)

Django - Passing parameters to inline formset

How about utilizing the inlineformset_factory's formfield_callback param instead of providing a formset ? Provide a callable which in turns returns the field which should be used in the form.

Form fields callback gets as 1st parameter the field, and **kwargs for optional params (e.g: widget).

For example (using request.user for the filter, replace with another if needed:

def my_view(request):
#some setup code here

def get_field_qs(field, **kwargs):
formfield = field.formfield(**kwargs)
if field.name == 'client':
formfield.queryset = formfield.queryset.filter(user=request.user)
return formfield

AttendanceFormset = inlineformset_factory(
...
formfield_callback=get_field_qs
...
)

formset = AttendanceFormset(request.POST, instance=session)

To better understand it, see the usage of formfield_callback in Django's FormSet code.

How to pass parameter from views to formset Django

You can do it by overriding the get_form_kwargs method in Class Based View. Here is a small description in the documentation and here you can find the source code.

What get_form_kwargs does is passing a dictionary of keywords arguments to __init__ in a form. So you have to change your code in two places - views.py and forms.py.

The example:

views.py

class CreatePost(generic.CreateView):
# SOMETHING HERE

def get_from_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update({"user", self.request.user})
return kwargs

forms.py

class PostForm(forms.ModelForm):
# SOMETHING HERE

def __init__(self, *args, **kwargs):
user = kwargs.pop("user", None)
super().__init__(*args, **kwargs)
if user is not None:
self.fields["group"].queryset = models.Group.object.filter(members = user)

What I am doing in the code above is passing the user from views to forms and then getting the queryset of the groups to which user belongs to (in Group model there is members ManyToManyField).

Someone posted also another example here.



Related Topics



Leave a reply



Submit