Django Tutorial
Django Create A Complete Project
Django Template
Django Database Query
Django Form
Django Authentication and Permission Management
Django unittest
Django Advanced
Django ModelForm is a convenient way to create forms that deal with model instances and their fields. ModelForm automatically generates form fields based on the fields in the associated model. In this tutorial, we will learn how to use Django ModelForm:
Assuming you have an existing Django model like the one below:
# models.py from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=100) publication_date = models.DateField() def __str__(self): return self.title
To create a ModelForm, create a new file called forms.py
in your app directory and add the following code:
# forms.py from django import forms from .models import Book class BookForm(forms.ModelForm): class Meta: model = Book fields = ['title', 'author', 'publication_date']
The BookForm
class inherits from forms.ModelForm
, and in the Meta
class, we specify the model (Book
) and the fields we want to include in the form. In this case, we include all fields of the Book
model.
Next, let's create a view to handle the form submission and rendering. In your views.py
file, add the following code:
from django.shortcuts import render, redirect from .models import Book from .forms import BookForm def create_book(request): if request.method == 'POST': form = BookForm(request.POST) if form.is_valid(): form.save() return redirect('books') # Replace 'books' with the name of your view that lists all books. else: form = BookForm() return render(request, 'create_book.html', {'form': form})
In this view, we first check if the request is a POST request. If so, we create an instance of the BookForm
using the submitted data. We then validate the form, save the instance if the form is valid, and redirect to the list of all books. If the request is a GET request, we create an empty instance of the BookForm
.
Now, let's create a template for our form. Create a new file called create_book.html
in your app's templates directory and add the following code:
{% extends 'base.html' %} {% block content %} <h2>Create Book</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Save</button> </form> {% endblock %}
In this template, we include a form with a POST method, add a CSRF token for security, and render the form fields using {{ form.as_p }}
. This renders each form field as a paragraph. You can also use {{ form.as_table }}
or {{ form.as_ul }}
to render the fields as table rows or list items, respectively.
The view we created in step 2 already handles saving data using the ModelForm. When the form is submitted with a POST request, we create an instance of the BookForm
using the submitted data. We then validate the form, save the instance if the form is valid, and redirect to the list of all books.
Here's a closer look at the saving process:
form = BookForm(request.POST)
: We create an instance of the BookForm
using the data submitted with the POST request. If the request contains files, you need to pass the request.FILES
dictionary as well: form = BookForm(request.POST, request.FILES)
.
if form.is_valid()
: We check if the form is valid. If the form is valid, the underlying model instance's fields are populated with the cleaned data from the form. The is_valid()
method also runs any custom validation methods you might have defined in the form.
form.save()
: We save the model instance associated with the form. This method creates a new model instance in the database if the form is handling a new object, or updates the existing instance if the form is handling an existing object. To update an existing object, you need to create the form with the instance: form = BookForm(request.POST, instance=book)
.
That's it! Saving data using a Django ModelForm is simple and efficient. By using ModelForms, you can save time and avoid writing boilerplate code for handling form submission, validation, and saving.
Creating forms from models in Django:
from django import forms from .models import MyModel class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = '__all__'
Django ModelForm example code:
from django import forms from .models import MyModel class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = '__all__'
Django forms for model instances:
instance = MyModel.objects.get(pk=1) form = MyModelForm(instance=instance)
ModelForm save method in Django:
form = MyModelForm(request.POST) if form.is_valid(): instance = form.save()
Django ModelForm fields and widgets:
class MyModelForm(forms.ModelForm): custom_field = forms.CharField(widget=forms.Textarea) class Meta: model = MyModel fields = '__all__'
Customizing Django ModelForm behavior:
class MyModelForm(forms.ModelForm): def clean_custom_field(self): # Custom cleaning logic return cleaned_data['custom_field'].upper() class Meta: model = MyModel fields = '__all__'
Django ModelForm validation and cleaning:
class MyModelForm(forms.ModelForm): def clean_custom_field(self): # Custom cleaning logic return cleaned_data['custom_field'].upper() class Meta: model = MyModel fields = '__all__'
Django ModelForm initial data:
initial_data = {'field1': 'value1', 'field2': 'value2'} form = MyModelForm(initial=initial_data)
Django ModelForm for updating instances:
instance = MyModel.objects.get(pk=1) form = MyModelForm(request.POST, instance=instance)
Working with formsets and ModelForm:
from django.forms import modelformset_factory MyModelFormSet = modelformset_factory(MyModel, form=MyModelForm)
Django ModelForm and related models:
class RelatedModelForm(forms.ModelForm): class Meta: model = RelatedModel fields = '__all__' class MyModelForm(forms.ModelForm): related_model_form = RelatedModelForm() class Meta: model = MyModel fields = '__all__'
Dynamic forms with Django ModelForm:
class MyModelForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(MyModelForm, self).__init__(*args, **kwargs) if some_condition: self.fields['custom_field'] = forms.CharField() class Meta: model = MyModel fields = '__all__'
Django ModelForm and form inheritance:
class BaseForm(forms.ModelForm): # Base form fields and behavior class MyModelForm(BaseForm): # Additional fields or overrides class Meta: model = MyModel fields = '__all__'
Handling form submissions in Django views:
def my_view(request): if request.method == 'POST': form = MyModelForm(request.POST) if form.is_valid(): # Process form data else: form = MyModelForm()
Using Django ModelForm in class-based views:
from django.views.generic.edit import CreateView from .models import MyModel from .forms import MyModelForm class MyModelCreateView(CreateView): model = MyModel form_class = MyModelForm template_name = 'my_model_form.html' success_url = '/success/'