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
Pandas Groupby Multiple Fields Then Diff
Is There a Math Ncr Function in Python
Pandas - Slice Large Dataframe into Chunks
How to Check If Type of a Variable Is String
How to Download a File on a Click Event Using Selenium
How to Get the Utc Time of "Midnight" for a Given Timezone
How to Open Every File in a Folder
What Does the Percentage Sign Mean in Python
How to Run Spyder in Virtual Environment
Differencebetween Slice Assignment That Slices the Whole List and Direct Assignment
Function for Factorial in Python
How to Get First Element in a List of Tuples
Get the Second Largest Number in a List in Linear Time
Pandas Dataframe: Replace All Values in a Column, Based on Condition
How to Implement a Python for Range Loop Without an Iterator Variable