Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django __init__ method causing argument error

Tags:

python

django

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...

like image 215
Md. Tanvir Raihan Avatar asked Jan 13 '16 06:01

Md. Tanvir Raihan


1 Answers

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:

  1. If all you want is a class-based create view that is compatible with formsets, use django-extra-views.

  2. 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.

like image 192
Burhan Khalid Avatar answered Oct 08 '22 19:10

Burhan Khalid