Home > Blockchain >  Update data inside class based detail view
Update data inside class based detail view

Time:01-23

I want to let the user edit their inputted data from the detail view directly. The data the user have previously entered should also be displayed.

This is my detail view right now:

class GeographyDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
    model = Geography

    def get_context_data(self, **kwargs):
        context = super(GeographyDetailView, self).get_context_data(**kwargs)
        context['form'] = GeographyForm()
        return context

    def post(self, request, pk):
        post=get_object_or_404(Geography, pk=pk)
        form = GeographyForm(request.POST)

        if form.is_valid():
            geo = form.save(commit=False)
            geo.student = self.request.user
            geo.save()
            return redirect('geography')
 
    def test_func(self):
        Geography = self.get_object()
        if self.request.user == Geography.student:
            return True
        return False here

Right now when I submit the form, instead of updating the data, a new one is created. I also don't know how to prefill the form with the data that was previously entered.

This is my forms.py file

class GeographyForm(forms.ModelForm):
class Meta:
    model = Geography
    fields = ('title', 'rep1', 'rep2', 'rep3', 'rep4', 'rep5')

This is my html template

<div >
<h1>{{object.title}}</h1>
<div>
    <form action="" method="POST">
        {%csrf_token%}
        {{form}}
        <button type="submit">Bekräfta</button>
    </form>
</div>
<hr>

CodePudding user response:

What you here describe is in essence an UpdateView [Django-doc]. I would suggest that you use this with:

from django.urls import reverse_lazy

class GeographyDetailView(LoginRequiredMixin, UpdateView):
    model = Geography
    form_class = GeographyForm
    success_url = reverse_lazy('geography')
    template_name = 'some_template.html'

    def get_queryset(self):
        return super().get_queryset().filter(
            student=self.request.user
        )

This should be sufficient: it will pass the object to edit as object to the context, and the form as form to the rendering context.

The form should be submitted to the same view as this one and will redirect to the geography view in case the form is valid.

The get_queryset filters on the student. This means that it will return a HTTP 404 response in case the user that aims to edit the object is not the student of that object.

  •  Tags:  
  • Related