Form errors in ListFormsetView created by adding methods to a ListView.

25 views
Skip to first unread message

VISHESH MANGLA

unread,
Jun 11, 2021, 7:05:20 AM6/11/21
to Django users
Hello, 

I am consistently getting this bizarre error and formset_invalid is getting triggered.
I just tried to make a generic ListFormSetView.

[11/Jun/2021 12:48:24] "GET /adminuser/print-report/?page=1 HTTP/1.1" 200 5244
[{'PAN_ID': ['User with this Pan ID already exists.']}]
[11/Jun/2021 12:59:29] "POST /adminuser/print-report/?page=2 HTTP/1.1" 200 5250

In my model the USERNAME_FIELD  is PAN_ID.

Webpage looks like this

Code:

class PrintStatementView(ListFormSetView):
    paginate_by = 1
    model = User
    form_class = PrintReportModelForm
    template_name = "adminuser/printstatement.html"
    context_formset_name = "formset"
    ordering = ("PAN_ID",)

    def get_factory_object(self):
        return modelformset_factory(
            self.model,
            form=self.form_class,
            extra=0,
        )

    def formset_valid(selfformset):
        self.request.session.setdefault("to_download", [])
        self.request.session["to_download"][self.kwargs["page"]] = [
            x["PAN_ID"]
            for x in formset.cleaned_data
            if x["print_report_check"]
        ]
        return HttpResponseRedirect(
            f"{reverse('print-report')}?page={self.kwargs['page']}"
        )

    def get_success_url(self):
        return reverse("adminuser:trading-window-list")





class ListFormSetView(ListView):
    def get_factory_object(self):
        return NotImplementedError(" Implement yourself ")

    def get_context_data(self, *, object_list=None, **kwargs):

        context_formset_name = (
            getattr(self"context_formset_name"Noneor "formset"
        )

        context_data = super().get_context_data(**kwargs)

        object_list = context_data["object_list"]
        context_data[context_formset_name] = self.get_factory_object()(
            queryset=object_list, initial=self.get_initial(object_list)
        )

        return context_data

    def get_form_kwargs(self):

        context_data = super().get_context_data()

        object_list = context_data["object_list"]

        kwargs = {
            "initial"self.get_initial(object_list),
            "queryset": object_list,
        }
        if self.request.method in ("POST""PUT"):
            kwargs.update(
                {
                    "data"self.request.POST,
                    "files"self.request.FILES,
                }
            )
        return kwargs

    def get_initial(selfqueryset=[]):
        """ Generate the initial data for the paginated queryset for the current page"""
        try:
            return self.initial
        except AttributeError:
            data = serializers.serialize("json", queryset)
            data = json.loads(data)
            return data

    def post(selfrequest, *args, **kwargs):
        self.object_list = self.get_queryset()
        formset = self.get_factory_object()(**self.get_form_kwargs())

        if formset.is_valid():
            return self.formset_valid(formset)
        else:
            return self.formset_invalid(formset)

    def formset_valid(selfformset):
        return HttpResponseRedirect(self.get_success_url())

    def formset_invalid(selfformset):
        print(formset.errors)
        return self.render_to_response(self.get_context_data(formset=formset))



Lalit Suthar

unread,
Jun 11, 2021, 11:04:36 AM6/11/21
to django...@googlegroups.com
possibly you are requesting with the same pan id again

VISHESH MANGLA

unread,
Jun 11, 2021, 5:18:09 PM6/11/21
to Django users
Sorry , I should have posted the template
well, the error is,  hmm,
suppose you are at  page 1  , now you clicked next and you got to page 2 and the `post` method is hit. It will get page number as 2. But for  formset , the initial data will have to be compared with  page "1" s data not "2". In the current scenario ,the initial_data  was the page2's but the data that was posted was for page 1. So you see the problem? It took me quite long to understand this.

 
 


{% extends 'adminuser/portal.html' %} 
{% block main-content %}
{% load my_extra_filters %}
 {% if messages %}
{% for message in messages %}

<div class="alert alert-success" role="alert">{{ message }}</div>
{% endfor %}
 {% endif %}

<form method="post" >

  {% csrf_token %}
  {{ formset.management_form }}

  <table class="table">
    <thead>
      <tr>
        <th scope="col">Name</th>
        <th scope="col">Pan ID</th>
        <th scope="col">Print Report?</th>
      </tr>
    </thead>

    <tbody>
      {% for user_form in formset %}
        {% for user_data in object_list %}
          {% if forloop.counter0 == forloop.parentloop.counter0 %}
              <tr>
                <td>{{user_data.get_full_name.}}</td>
                <td>{{user_data.PAN_ID}}</td>
                {{user_form.PAN_ID}}
                
                <td>{{user_form.print_report_check}}</td>
              </tr>
      
          {% endif %}
        {% endfor %}
    
      {% endfor %}


    </tbody> 
  </table>
<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <button class="btn btn-dark"  formaction="?page=1">&laquo; first</button>
            <button class="btn btn-dark" formaction="?page={{ page_obj.previous_page_number }}">previous</button>
        {% endif %}

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <button class="btn btn-dark" formaction="?page={{ page_obj.next_page_number }}">next</button>
            <button class="btn btn-dark" formaction="?page={{ page_obj.paginator.num_pages }}">last &raquo;</button>
        {% endif %}
    </span>
</div>

  <button class="btn btn-dark">Print</button>

</form>

{% endblock main-content%}

Reply all
Reply to author
Forward
0 new messages