1

I am using Django and Postgresql as database. I have a HTML page with two fields name and item. I can save the data in the database by clicking on submit. But, I want to show the saved data from database in the HTML page. It means, whenever we load the page, it should show the existing saved data and after submitting new data, the list should be updated. Below is my python code.

models.py

from django.contrib.auth.models import User
from django.db import models

class AllocationPlan(models.Model):

    name = models.CharField(max_length=50)
    item = models.CharField(max_length=4096)

views.py

class HomePageView(TemplateView):
    template_name = "index.html"
    def post(self, request, **kwargs):
        if request.method == 'POST':
            form = AllocationPlanForm(request.POST)
            if form.is_valid():
                form.save()

        return render(request, 'index.html', { 'form': AllocationPlanForm() })

forms.py

from django import forms
from django.forms import ModelForm
from homeapp.models import AllocationPlan   

class AllocationPlanForm(ModelForm):
    class Meta:
        model = AllocationPlan
        fields = "__all__" 

index.html

<html>
<form method="post">{% csrf_token %}
     Name:<br>
  <input type="text" name="name" >
  <br>
  Item:<br>
  <input type="text" name="item" >
  <br><br>
     <input type="submit" value="Submit"/>

 </form>
{% for i in form %}
{{ i.name }}
{{ i.item }}
{% endfor %}
</html>

It is returning NONE

1 Answer 1

2

Forms in Django are not used to display lists of data. It's merely used to render / validate the form (<form> tag in html). See also the forms doc.

Furthermore, it seems like you're using the TemplateView incorrectly. The post method in your view is only called on a POST request. When you're just viewing the page normally, the template is rendered normally, but since you only add the data to the template in a POST request, the template does not receive a form parameter when loading the view normally (therefore defaulting to None).

According to the TemplateView documentation, you can add the context like so:

class HomePageView(TemplateView):

    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(HomePageView, self).get_context_data(**kwargs)
        # Get the allocation plans from database. Limit to last 10. Adjust to your own needs
        context['plans'] = AllocationPlan.objects.all()[:10]
        context['form'] = AllocationPlanForm()
        return context

    def post(self, request, **kwargs):
        form = AllocationPlanForm(request.POST)
        if form.is_valid():
            form.save()
        # Handle rest of request here (for example, return the updated page).

As you can see, there is no need to check if request.method == 'POST' in your post method, because Django only calls this method on POST requests. See also dispatch in the docs

To render the data from your database you can now access them in your template as plans:

{% for plan in plans %}
{{ plan.name }}
{{ plan.item }}
{% endfor %}

In your HTML, there is also no need to manually create the form content:

<form method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

This will automatically create the HTML necessary for the form.

Sign up to request clarification or add additional context in comments.

1 Comment

Where @Randyr says "Handle rest of request here..." one would usually redirect to the same view (so the get request is processed): return redirect(reverse('url_pattern_name'))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.