How do I use Django generic updateviews to update my model using individual form field values?

54 views Asked by At

models.py:

from django.db import models

class Location(models.Model):
    name = models.CharField(max_length=20)
    is_source = models.BooleanField(default=False)
    is_destination = models.BooleanField(default=False)

    def __str__(self):
        return self.name

views.py

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views import generic
from .models import Location

class LocationsListView(generic.ListView):
    model = Location
    template_name = 'locations/list.html'
    context_object_name = 'locations'


class LocationUpdateView(generic.edit.UpdateView):
    model = Location
    fields = ['name', 'is_source', 'is_destination']
    context_object_name = 'location'
    template_name = 'locations/update.html'
    success_url = reverse_lazy('locations:list')

class LocationDeleteView (generic.edit.DeleteView):
    model = Location
    template_name = 'locations/confirm_delete.html'
    context_object_name = 'location'
    success_url = reverse_lazy('locations:list')

locations/update.html

{% extends 'base.html' %}

{% block title %}Location Update{% endblock %}

{% block content %}

<section>
    <div class="container">
        <h1>Location Update</h1>
        <div class="form-container">
            <form method="post">
                {% csrf_token %}
                {% if form.errors %}
                <div class="p-3 mb-3 border border-danger border-3 rounded">{{ form.errors }}</div>
                {% endif %}
                <div class="mb-3">
                    <label for="" class="form-label">Name</label>
                    <input type="text" class="form-control" value="{{ form.name.value }}">
                </div>
                <div class="mb-3">
                    <input type="checkbox" class="form-check-input" {% if form.is_source.value %} checked {% endif %}>
                    <label for="">Source</label>
                </div>
                <div class="mb-3">
                    <input type="checkbox" class="form-check-input" {% if form.is_destination.value %} checked {% endif %}> 
                    <label for="">Destination</label>
                </div>
                <input type="submit" class="btn btn-success mb-3" value="Save">
            </form>
        </div>
    </div>
</section>

{% endblock %}

locations.urls.py

from django.urls import path
from . import views

app_name = 'locations'


urlpatterns = [
    path('', views.LocationsListView.as_view(), name='list'),
    path('update/<int:pk>/', views.LocationUpdateView.as_view(), name='update'),
    path('delete/<int:pk>/', views.LocationDeleteView.as_view(), name='delete'), 
]

When I try to update my model, individually rendering the form fields using {{form.name.value}}, I get an error that my name field is required, and yet it is filled. I do not get the error if I render the form as a whole using {{form.as_p}} for example. What am I doing wrong?

I tried using {{form.as_p}} and it worked. But I need individual field rendering so I can style my form.

1

There are 1 answers

1
Iain Shelvington On BEST ANSWER

You need to provide the name attribute for each of your field <input> tags. The field's html_name attribute should be used if rendering manually

<input name="{{ form.name.html_name }}" type="text" class="form-control" value="{{ form.name.value }}">