I want to use django formset in my class based view. this is the view,
class PeriodCreate(RequestPassingFormViewMixin, WammuCreateView):
model = Chain
template_name = 'dashboard/period_form.html'
form_class = ChainForm
def get_object(self):
chain = Chain.objects.get(pk=self.kwargs['chain_pk'])
return chain
def get_success_url(self):
return reverse('dashboard_period_list', kwargs={'chain_pk': self.object.chain.id, })
def get_context_data(self, **kwargs):
context = super(PeriodCreate, self).get_context_data(**kwargs)
return context
def get_form_kwargs(self, *args, **kwargs):
kwargs = super(PeriodCreate, self).get_form_kwargs(*args, **kwargs)
chain = get_object_or_404(Chain, pk=self.kwargs['chain_pk'])
period = Period(chain=chain)
kwargs['instance'] = period
return kwargs
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
PeriodInlineFormSet = inlineformset_factory(Chain, Period,
form=PeriodInlineForm,
can_delete=True,
extra=12)
PeriodInlineFormSet.form = staticmethod(curry(PeriodInlineForm, request=request, chain=self.object))
period_formset = PeriodInlineFormSet()
return self.render_to_response(
self.get_context_data(form=form,
period_inline_formset=period_formset))
def post(self, request, *args, **kwargs):
self.object = Chain()
form = self.get_form(self.form_class)
PeriodInlineFormSet = inlineformset_factory(Chain, Period,
form=PeriodInlineForm,
can_delete=True,
extra=5)
PeriodInlineFormSet.form = staticmethod(curry(PeriodInlineForm))
if form.is_valid():
self.object = form.save(commit=False)
period_formset = PeriodInlineFormSet(request.POST, instance=self.object)
if period_formset.is_valid():
self.object.save()
period_formset.save()
return super(PeriodCreate, self).form_valid(form)
else:
return self.render_to_response(
context=self.get_context_data(form=form, period_inline_formset=period_formset))
else:
period_formset = PeriodInlineFormSet(request.POST,instance=self.object)
return self.render_to_response(
context=self.get_context_data(form=form, period_inline_formset=period_formset))
and this is my form,
class PeriodForm(RequestPassingFormMixin, ModelForm):
class Meta:
model = Period
fields = ['start_date', 'end_date', 'year', 'description']
and here is my 'RequestPassingFormMixin':
class RequestPassingFormMixin(object):
def __init__(self, request, param, *args, **kwargs):
self.request = request
self.param = param
super(RequestPassingFormMixin, self).__init__(*args, **kwargs)
but i am getting the following error,
TypeError at ....
__init__() takes at least 3 arguments (2 given)
this error indicating the template where i have rendered the formset,so i am giving the template also (only the part where i have rendered the forest),
<tbody>
{% csrf_token %}
{{ period_inline_formset.management_form }}
{% for period_form in period_inline_formset %}
{% for hidden in period_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{{period_form.pk}}
<tr>
<td>{{ period_form.start_date }}</td>
<td>{{ period_form.end_date }}</td>
<td>{{ period_form.year }}</td>
<td>{{ period_form.description }}</td>
<td> {% if period_formset.can_delete %}
{{ period_form.DELETE }} {% endif %}</td>
</tr>
{% endfor %}
</tbody>
I am not used to using django formset,as far i guess,its not a formset error, or it might be, maybe I am missing something else here,but after a long findings, I can't figure it out...
You have a few issues with your code; but to start off with the actual error - you are only passing in *args
, **kwargs
to the __init__
method of RequestPassingFormMixin
, when in the definition it takes two additional positional mandatory arguments, namely request
and param
.
The offending line is:
super(RequestPassingFormMixin, self).__init__(*args, **kwargs)
You really don't even need this line; since you are not overriding anything. You can just remove it.
In fact, you can remove this entire mixin, if that's all it does because the request and the parameters are available to all class based views already.
Also, I have no idea why you are using this mixin as a parent for your form class - it is not required there at all; and it won't do what you want it to do.
You have some other issues - you are overriding methods, but you don't change their functionality, so your code doesn't actually do anything different.
I have a few suggestions:
If all you want is a class-based create view that is compatible with formsets, use django-extra-views
.
This line chain = Chain.objects.get(pk=self.request.session.get('chain_pk'))
is not setting chain
anywhere in the class, so it is effectively lost. I am not sure why you have this line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With