SoFunction
Updated on 2024-11-19

Django ModelForm component usage details

I. Create ModelForm

from  import ModelForm
from appxx import models
from  import widgets as wdt # Alias because of a double name
# Define a class, such as BookForm, this class to inherit ModelForm, in this class and then write an original class Meta (specify the writing style, note that the first letter is capitalized)
# In this original class, there are the following properties (in part):
class BookForm(ModelForm):
  class Meta:
    model =  # Classes in the corresponding Model
    fields = "__all__" # fields, if __all__ means list all fields, or use a list to list the desired fields
    exclude = None # of fields excluded
    # error_messages usage
    error_messages = {
      "title": {"required": "The title of the book cannot be empty."},
      "price": {"required": "The selling price cannot be empty."},
    }
    # widgets usage, e.g. give the input box where you enter your username to Textarea
    widgets = {
      "name": (attrs={"class": "c1"}) # Can also customize attributes
    }
    #labels, customize the names displayed on the front end
    labels= {
      "title": "Title of the book.",
      "price": "Selling price",
    }

Then instantiate the class in the view function corresponding to the url and pass the object to the frontend:

def add_book(request):
  form = ()
  return render(request, "add_book.html", {"form": form})

The page is then rendered on the front end like a Form component

II. Adding data

When you save the data, you don't need to fetch the data one by one, you just need to save it.

from  import render,redirect
from appxx import models
from appxx import forms


def add_book(request):
  if  == "POST":
    form = ()
    if form.is_valid():
      ()
      return redirect("/book/")
  form = ()
  return render(request, "add_book.html", {"form": form})

III. Editing data

If you do not use ModelForm, you have to display the previous data when editing, but also have to take the value of one by one; if you use ModelForm, you just need to add an instance=obj (obj is the object of a piece of data in the database to be modified) to get the same effect.

Be careful when saving, be sure to note that you have this object (instance=obj), otherwise you won't know which data to update.

from  import render,redirect
from appxx import models
from appxx import forms


def edit_book(request, edit_book_id):
  edit_book= (id=edit_book_id).first()
  if  == "POST":
    form = (, instance=edit_book)
    if form.is_valid():
      ()
      return redirect("/book/")
  form = (instance=edit_book)
  return render(request, "edit_book.html", {"form": form})

Summary: From the above you can see that ModelForm is very convenient to use , such as adding changes and other operations. But it also brings additional bad places , model and form coupled. If not coupled, () method can not be submitted directly to save. But the coupling of the use of the scene is usually limited to small programs, write a large program it is best not to use.

IV. Complete sample code

Project structure

from  import url
from  import admin
from appxx import views


urlpatterns = [
  url(r'^admin/', ),
  url(r"^book/$", ),
  url(r"^book/add/", views.add_book),
  url(r"^book/edit/(\d+)/", views.edit_book),
]

from  import render,redirect
from appxx import models
from appxx import forms


def book(request):
  book_list = ()
  return render(request, "", {"book_list": book_list})


def add_book(request):
  if  == "POST":
    form = ()
    if form.is_valid():
      ()
      return redirect("/book/")
  form = ()
  return render(request, "add_book.html", {"form": form})


def edit_book(request, edit_book_id):
  edit_book= (id=edit_book_id).first()
  if  == "POST":
    form = (, instance=edit_book)
    if form.is_valid():
      ()
      return redirect("/book/")
  form = (instance=edit_book)
  return render(request, "edit_book.html", {"form": form})

from  import models


class Book():
  id = (primary_key=True)
  title = (max_length=32)
  price = (max_digits=5, decimal_places=2)
  publish_date = ()
  publisher = (to="Publisher")
  authors = (to="Author")

  def __str__(self):
    return 


class Publisher():
  id = (primary_key=True)
  name = (max_length=32)

  def __str__(self):
    return 


class Author():
  id = (primary_key=True)
  name = (max_length=32)

  def __str__(self):
    return 

from  import ModelForm
from appxx import models
from  import widgets as wdt


class BookForm(ModelForm):
  class Meta:
    model = 
    fields = "__all__"
    labels = {
      "title": "Title of the book.",
      "price": "Selling price",
      "publish_date": "Date of Publication",
      "publisher": "Publisher.",
      "authors": "Author."
    }
    widgets = {
      "title": (attrs={"class": "form-control"}),
      "price": (attrs={"class": "form-control"}),
      "publish_date": (attrs={"class": "form-control", "type": "date"}),
      "publisher": (attrs={"class": "form-control"}),
      "authors": (attrs={"class": "form-control"}),

    }
    error_messages = {
      "title": {"required": "The title of a book cannot be empty."},
      "price": {"required": "The selling price cannot be empty."},
      "publish_date": {"required": "Publication date cannot be null."},
      "publisher": {"required": "Publishers can't be empty."},
      "authors": {"required": "The author cannot be empty."},
    }

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title>Showcase Books</title>
  <link rel="stylesheet" href="/static/bootstrap/css/" rel="external nofollow" rel="external nofollow" >
</head>
<body>
<div class="container">
  <div class="row">
    <div class="col-md-6 col-md-offset-3">
      <span><a class="btn btn-primary" href="/book/add/" rel="external nofollow" >increase</a></span>
      <table class="table table-striped table-bordered">
        <thead>
        <tr>
          <th>serial number</th>
          <th>reputation as calligrapher</th>
          <th>selling prices</th>
          <th>date of publication</th>
          <th>publishers</th>
          <th>author</th>
          <th>manipulate</th>
        </tr>
        </thead>
        <tbody>
        {% for book in book_list %}
          <tr>
            <td>{{  }}</td>
            <td>{{  }}</td>
            <td>{{  }}</td>
            <td>{{ book.publish_date }}</td>
            <td>{{  }}</td>
            <td>
              {% for author in  %}
                {{  }}
              {% endfor %}
            </td>
            <td>
              <span><a class="btn btn-warning" href="/book/edit/{{  }}/" rel="external nofollow" >compiler</a></span>
              <span><a class="btn btn-danger" href="">removing</a></span>
            </td>
          </tr>
        {% endfor %}
        </tbody>
      </table>
    </div>
  </div>
</div>
</body>
</html>

add_book.html and edit_book.html (same code for both pages)

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title>Add Books</title>
  <link rel="stylesheet" href="/static/bootstrap/css/" rel="external nofollow" rel="external nofollow" >
  <style>
    .panel-title {
      font-weight: bolder;
    }

    .panel {
      margin-top: 30px;
    }
  </style>
</head>
<body>
<div class="container">
  <div class="row">
    {# Panel starts #}
    <div class="panel panel-danger col-sm-6 col-md-6 col-sm-offset-3 col-md-offset-3">
      <div class="panel-heading">
        <h3 class="panel-title">Add Books</h3>
      </div>
      {# panel-body starts #}
      <div class="panel-body">
        {# form start #}
        <form class="form-horizontal" action="" method="post" novalidate>
          {% csrf_token %}
          <div class="form-group">
            <label class="col-md-2 control-label"
                for="{{ .id_for_label }}">{{  }}</label>
            <div class="col-md-10">
              {{  }}
            </div>
          </div>
          <div class="form-group">
            <label class="col-md-2 control-label"
                for="{{ .id_for_label }}">{{  }}</label>
            <div class="col-md-10">
              {{  }}
            </div>
          </div>
          <div class="form-group">
            <label class="col-md-2 control-label"
                for="{{ form.publish_date.id_for_label }}">{{ form.publish_date.label }}</label>
            <div class="col-md-10">
              {{ form.publish_date }}
            </div>
          </div>
          <div class="form-group">
            <label class="col-md-2 control-label"
                for="{{ .id_for_label }}">{{  }}</label>
            <div class="col-md-10">
              {{  }}
            </div>
          </div>
          <div class="form-group">
            <label class="col-md-2 control-label"
                for="{{ .id_for_label }}">{{  }}</label>
            <div class="col-md-10">
              {{  }}
            </div>
          </div>
          <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
              <button type="submit" class="btn btn-success">submit (a report etc)</button>
              <a class="btn btn-warning pull-right" href="/book/" rel="external nofollow" >abolish</a>
            </div>
          </div>
        </form>
        {# End of form #}
      </div>
      {# panel-body end #}
    </div>
    {# End of panel #}
  </div>
</div>
</body>
</html>

This is the whole content of this article.