# Django Form vs HTML form

**URL:** <https://forum.djangoproject.com/t/django-form-vs-html-form/8570>\
**Category:** Using Django\
**Created:** [June 29, 2021, 5:35pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570 "2021-06-29T17:35:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![anxious01210](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anxious01210/32/2595_2.png) [@anxious01210](https://forum.djangoproject.com/u/anxious01210)\
**Post date:** [June 29, 2021, 5:35pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/1 "2021-06-29T17:35:35Z")

</div>

Hello,

What is the difference between model based or normal Django form and normal html form for being used in CRUD?  
By normal HTML form I mean just get the HTML form fields by name and values in the request.POST.get and then using it for Create/update with the help of {% csrf\_token %}.  
I mean is it wrong or OK?

Thank you.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 29, 2021, 6:01pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/2 "2021-06-29T18:01:19Z")

</div>

An html form is only what is rendered in the browser. A Django form is a _lot_ more than that. The [Working with forms](https://docs.djangoproject.com/en/3.2/topics/forms/#working-with-forms) page covers this in a lot more detail, and does a better job than what I could do here.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 29, 2021, 6:12pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/3 "2021-06-29T18:12:59Z")

</div>

> [@anxious01210](#):
>
> I mean is it wrong or OK?

`<opinion>`  
I would go on to say that I consider it **very** wrong. The facilities provided by the Django forms consists of a lot of features that you should be doing (or must do) when processing form input. (This includes things like validating fields, checking form integrity, performing data type conversions, etc.)

You can either write the code yourself to do all that - in which case I’d be asking why you’re even bothering to use Django at all, or you can use Django as designed and intended.  
`</opinion>`

---

<div class="post-metadata">

**Author:** ![anxious01210](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anxious01210/32/2595_2.png) [@anxious01210](https://forum.djangoproject.com/u/anxious01210)\
**Post date:** [June 29, 2021, 6:54pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/4 "2021-06-29T18:54:00Z")

</div>

Hello,

I do that because when I use a bootstrap theme for the front-end it has beautiful style and if I use the HTML form fields names & values with request.POST.get in my views.py then the style of the front-end will stay the same as it was designed for all the screen sizes, … .  
So I wanted to know that if it was ok then I will do the same in my project.

Here I copied a piece of the code from the related .py files for you to check:

Hello Ken,

## Thanks for the explanation. Here is example that I am talking about.

sm\_app.Models.py :

# Overriding the Default Django Auth User and adding One More Field (user\_type)

class CustomUser(AbstractUser):  
“”“Django data model CustomUser”“”  
user\_type\_data = ((1, ‘HOD’), (2, ‘Teacher’), (3, ‘Student’), (4, ‘Parent’), (5, ‘Staff’))  
user\_type = models.CharField(default=1, choices=user\_type\_data, max\_length=10)

class Parent(models.Model):  
“”“Django data model Admin”“”  
admin = models.OneToOneField(CustomUser, on\_delete=models.CASCADE, blank=True, null=True)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

class Staff(models.Model):  
“”“Django data model Admin”“”  
admin = models.OneToOneField(CustomUser, on\_delete=models.CASCADE, blank=True, null=True)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

class AdminHOD(models.Model):  
“”“Django data model Admin”“”  
admin = models.OneToOneField(CustomUser, on\_delete=models.CASCADE, blank=True, null=True)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

class Teacher(models.Model):  
“”“Django data model Teacher”“”  
admin = models.OneToOneField(CustomUser, on\_delete=models.CASCADE, blank=True, null=True)  
address = models.TextField()  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

class Course(models.Model):  
“”“Django data model Course”“”  
course\_name = models.CharField(max\_length=100)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

```
# def __str__ (self):
# return str(self.course_name)

```

class Subject(models.Model):  
“”“Django data model Subject”“”  
course\_id = models.ForeignKey(Course, on\_delete=models.CASCADE)  
teacher\_id = models.ForeignKey(CustomUser, on\_delete=models.CASCADE)  
subject\_name = models.CharField(max\_length=100)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

```
# def __str__ (self):
# return str(self.subject_name)

```

class Student(models.Model):  
“”“Django data model Student”“”  
admin = models.OneToOneField(CustomUser, on\_delete=models.CASCADE, blank=True, null=True)  
gender = models.CharField(max\_length=100)  
profile\_pic = models.ImageField(upload\_to=“SM\_app/students”)  
address = models.TextField()  
course\_id = models.ForeignKey(Course, on\_delete=models.DO\_NOTHING)  
session\_start\_year = models.DateField(blank=True, null=True)  
session\_end\_year = models.DateField(blank=True, null=True)  
created\_at = models.DateTimeField(auto\_now\_add=True)  
updated\_at = models.DateTimeField(auto\_now=True)

```
# def __str__ (self):
# return str(self.admin.first_name)

```

## . . .

Part of sm\_app.urls.py :

```
path('add_student/', HoDViews.add_student, name='add_student'),
path('add_student_save/', HoDViews.add_student_save, name='add_student_save'),
path('edit_student/<str:student_id>/', HoDViews.edit_student, name='edit_student'), 
path('edit_student_save/', HoDViews.edit_student_save, name='edit_student_save'),

```

## . . .

Part of views.py :

def add\_student(request):  
courses = Course.objects.all()  
context = {‘courses’: courses}  
return render(request, ‘hod\_template/add\_student\_template.html’, context)

def add\_student\_save(request):  
if request.method != ‘POST’:  
return HttpResponse(‘Method Not Allowed’)  
else:  
first\_name = request.POST.get(‘first\_name’)  
last\_name = request.POST.get(‘last\_name’)  
username = request.POST.get(‘username’)  
email = request.POST.get(‘email’)  
password = request.POST.get(‘password’)  
address = request.POST.get(‘address’)  
session\_start = request.POST.get(‘session\_start’)  
session\_end = request.POST.get(‘session\_end’)  
course\_id = request.POST.get(‘course’)  
gender = request.POST.get(‘gender’)

```
    try:
        # Manager methods¶ ==> https://docs.djangoproject.com/en/3.2/ref/contrib/auth/ - create_user is a method already defined in django.contrib.auth AbstractUser model and objects is the model manager here.
        user = CustomUser.objects.create_user(username=username, password=password, email=email,
                                              first_name=first_name, last_name=last_name, user_type=3)
        user.student.address = address
        course_obj = Course.objects.get(id=course_id)
        user.student.course_id = course_obj
        user.student.session_start_year = session_start
        user.student.session_end_year = session_end
        user.student.gender = gender
        user.student.profile_pic = ''
        user.save()
        messages.success(request, 'Successfully added the Student.')
        return HttpResponseRedirect('/add_student')
    except:
        messages.error(request, 'Failed to add the Student.')
        return HttpResponseRedirect('/add_student')

```

def manage\_student(request):  
students = Student.objects.all()  
context = {‘students’: students}  
return render(request, ‘hod\_template/manage\_student\_template.html’, context)

def edit\_student(request, student\_id): # This student\_id is actually student.admin.id  
courses = Course.objects.all()  
student = Student.objects.get(admin=student\_id)  
context = {‘courses’: courses, ‘student’: student}  
return render(request, ‘hod\_template/edit\_student\_template.html’, context)

def edit\_student\_save(request):  
if request.method != ‘POST’:  
return HttpResponse(‘

## Method is not allowed!
’)  
else:  
student\_id = request.POST.get(‘student\_id’)  
first\_name = request.POST.get(‘first\_name’)  
last\_name = request.POST.get(‘last\_name’)  
username = request.POST.get(‘username’)  
email = request.POST.get(‘email’)  
address = request.POST.get(‘address’)  
session\_start = request.POST.get(‘session\_start’)  
session\_end = request.POST.get(‘session\_end’)  
course\_id = request.POST.get(‘course’)  
gender = request.POST.get(‘gender’)  
try:  
user = CustomUser.objects.get(id=student\_id)  
user.first\_name = first\_name  
user.last\_name = last\_name  
user.username = username  
user.email = email  
user.save()

```
        student = Student.objects.get(admin=student_id)
        student.address = address
        student.session_start_year = session_start
        student.session_end_year = session_end
        student.gender = gender

        course = Course.objects.get(id=course_id)
        student.course_id = course
        student.save()
        messages.success(request, 'Successfully Edited Student.')
        return HttpResponseRedirect('/edit_student/' + student_id)
    except:
        messages.error(request, 'Failed to Edit Student!')
        return HttpResponseRedirect('/edit_student/' + student_id)

```

## . . .

edit\_student\_save.html :

```
          <form role="form" action="{% url 'sm_app:edit_student_save' %}" method="post">
              {% csrf_token %}
            <div class="card-body">
              <div class="form-group">
                <label >Email address</label>
                <input type="email" class="form-control" placeholder="Enter email" name="email" value="{{ student.admin.email }}">
              </div>
              <div class="form-group">
                <label >First Name</label>
                <input type="text" class="form-control" placeholder="First Name" name="first_name" value="{{ student.admin.first_name }}">
              </div>
              <div class="form-group">
                <label >Last Name</label>
                <input type="text" class="form-control" placeholder="Last Name" name="last_name" value="{{ student.admin.last_name }}">
              </div>
              <div class="form-group">
                <label >Username</label>
                <input type="text" class="form-control" placeholder="Username" name="username" value="{{ student.admin.username }}">
                <input type="text" hidden name="student_id" value="{{ student.admin.id }}">
              </div>
              <div class="form-group">
                <label >Address</label>
                <input type="text" class="form-control" placeholder="Username" name="address" value="{{ student.address }}">
              </div>
              <div class="form-group">
                <label >Course</label>
                  <select class="form-control" name="course">
                    {% for course in courses %}
                        <!-- If the condition is satisfied then the option is selected -->
                        <option value="{{ course.id }}" {% if course.id == student.course_id.id %} selected {% endif %}>{{ course.course_name }}</option>
                    {% endfor %}
                  </select>
              </div>
              <div class="form-group">
                  <label>Gender</label>
                  <select class="form-control" name="gender">
                      <option value="" {% if student.gender == 'Male' %} selected {% endif %}>Male</option>
                      <option value="" {% if student.gender == 'Female' %} selected {% endif %}>Female</option>
                  </select>
              </div>
              <div class="form-group">
                  <label>Session Start</label>
                  <input type="date" class="form-control" placeholder="Session Start Year" name="session_start" value="{{ student.session_start_year|date:'Y-m-d' }}">
              </div>
              <div class="form-group">
                  <label>Session End</label>
                  <input type="date" class="form-control" placeholder="Session End Year" name="session_end" value="{{ student.session_end_year|date:'Y-m-d' }}">
              </div>
              <div class="form-group">
                  {% if messages %}
                      {% for message in messages %}
                          {% if message.tags == 'error' %}
                          <div class="alert alert-danger" style="margin-top: 10px;">{{ message }} </div>
                          {% endif %}
                          {% if message.tags == 'success' %}
                          <div class="alert alert-success" style="margin-top: 10px;">{{ message }} </div>
                          {% endif %}
                      {% endfor %}
                  {% endif %}
                  <!-- /.col -->
              </div>

            </div>
            <!-- /.card-body -->

            <div class="card-footer">
              <button type="submit" class="btn btn-primary btn-block">Update Student</button>
            </div>
          </form>

```

## . . .

Thanks.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 29, 2021, 7:16pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/5 "2021-06-29T19:16:41Z")

</div>

When posting code here, please enclose it between line of three backtick - ` characters. That ensures the code stays properly formatted.

Also, you can specify the css classes to be used in form fields - both for model forms and non-model forms. Hand-crafting the html provides no benefits.

If you’ve got a specific question as to how to handle something, please trim your code down to the smallest sample demonstrating the issue.

---

<div class="post-metadata">

**Author:** ![anxious01210](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anxious01210/32/2595_2.png) [@anxious01210](https://forum.djangoproject.com/u/anxious01210)\
**Post date:** [June 29, 2021, 7:37pm UTC](https://forum.djangoproject.com/t/django-form-vs-html-form/8570/6 "2021-06-29T19:37:52Z")

</div>

Noted.

Thank you very much.
