Search code examples
djangodjango-class-based-viewsformviewdetailview

Why FormView not saving data within a DetailView?


I have a DetailView Based on a model ( A ) and on the same template I have a ModelFormView from a model B which has FK to model (A)

The data from form doesn't get saved to the database.

This is the DetailView:

class LocationView(DetailView):

    template_name = "base/stocks/location.html"
    model = LocationStock

    def get_context_data(self, **kwargs):

         context = super(LocationView, self).get_context_data(**kwargs)
         context['form'] = OutsModelForm
         return context

    def get_object(self):

         id_ = self.kwargs.get("id")
         return get_object_or_404(LocationStock, id=id_)

This is the FormView:

  class OutsAdd(FormView):

       form_class = OutsModelForm
       success_url = reverse_lazy('base:dashboard')

       def form_valid(self, form):

           return super().form_valid(form)

This is the url.py:

    path('locations/<int:id>', LocationView.as_view(), name='location-detail'),
    path('locations/outs', require_POST(OutsAdd.as_view()), name='outs-add'),

This is the template:

<form method="POST" action="{% url 'outs-add' %}" >

<div class="modal-content">
        {% csrf_token %} 
          {% render_field form.quantity placeholder="Quantity"%}
          {% render_field form.id_year placeholder="Year"%}
          {% render_field form.id_location placeholder="ID Location"%}

  </div>
  <div class="modal-footer">
    <input class="modal-close waves-effect waves-green btn-flat" type="submit" value="Save">
  </div>
</form>

The data gets POSTED in the /locations/outs but is not saving to the actual database.How can I save it ?


Solution

  • The functionality of Django's FormView is really only meant to display a form on a GET request, show form errors in the case of form_invalid, and redirect to a new URL if the form is valid. In order to persist the data to the database you have two options. First you can simply call form.save() in your FormView:

    class OutsAdd(FormView):
        form_class = OutsModelForm
        success_url = reverse_lazy('base:dashboard')
    
        def form_valid(self, form):
            form.save()
            return super().form_valid(form)
    

    Or, you can use the generic CreateView. Django's CreateView is similar to a FormView except it assumes it's working with a ModelForm and calls form.save() for you behind the scenes.