Reference: Django builds personal blogs: Use the Form class to publish new posts
Forms the form class
Working with forms can be complicated. Django’s forms functionality simplifies most tasks, and is much safer than most programmers writing their own code.
The central component of Djangos forms system is the Form class.
In the same way that fields of a model class map to database fields, fields of a form class map to elements of an HTML form. ModelForm maps the fields of the model class through the Form to the element of the HTML Form on which Django Admin is based.
Building a form
Create the forms.py file in article/ and write:
article/forms.py
# Introduce form classes
from django import forms
# Introduce the article model
from .models import ArticlePost
# form class for writing articles
class ArticlePostForm(forms.ModelForm) :
class Meta:
Specify the source of the data model
model = ArticlePost
Define the fields that the form contains
fields = ('title'.'body')
Copy the code
- In the code
ArticlePostForm
Class inherits from Djangos form classesforms.ModelForm
And defines inner classes in the classclass Meta
Indicate where the data model comes from and which fields of the data model should be included in the form.- in
ArticlePost
In the model.created
andupdated
The field is automatically generated and does not need to be filled in;author
Field temporarily fixed toid=1
Administrator user, also do not need to fill; The rest of thetitle
andbody
That’s what the form needs to fill in.
Next, rewrite article/views.py and add a view function to handle article requests:
article/views.py
...
# introduce the Redirect redirect module
from django.shortcuts import render, redirect
# introduction HttpResponse
from django.http import HttpResponse
# Import the ArticlePostForm form class you just defined
from .forms import ArticlePostForm
# Introduce the User model
from django.contrib.auth.models import User
...
# View for writing articles
def article_create(request) :
Determine whether the user submits data
if request.method == "POST" :
Assign the submitted data to the form instance
article_post_form = ArticlePostForm (request.POST)
Determine whether the submitted data meets the requirements of the model
if article_post_form.is_valid():
Save the data, but do not commit to the database for the time being
new_article = article_post_form.save(commit=False)
Select * from user where id = 1 as author
new_article.author = User.objects.get(pk=1)
Save the new article to the database
new_article.save()
Return to the list of articles
return redirect("article:article_list")
If the data is invalid, return an error message
else:
return HttpResponse("The content of the form is wrong, please fill it out again.")
If the user requests the data
else:
Create a form class instance
article_post_form = ArticlePostForm()
# Assign context
context = {'article_post_form' : article_post_form }
# return template
return render(request,'article/create.html',context)
Copy the code
When a view function receives a request from a client, it first determines whether the user wants to POST or GET data based on request.method:
- If the user isSubmit dataAssigns the form data posted to the server to
article_post_form
Instance.
- Then use Django’s built-in methods
.is_valid()
Determine whether the submitted data meets the requirements of the model.
- ifMeet the requirementsSave the data in the form (but
commit=False
Do not commit to the database for now becauseauthor
Not yet specified) and specifyThe author of id = 1
Is the administrator user of. It then commits to the database and passesredirect
Returns a list of articles.redirect
You can use the name of the URL to reverse lookup to the corresponding URL.- If the requirements are not met, the user is returned with the string “The form content is wrong, please fill it out again” to tell the user what the problem is.
- If the user is retrieving data, an empty form-like object is returned for the user to fill in.
Once you’ve written the view, you need to write the template file. Create create.html in templates/article/ :
templates/article/create.html
<! --extends indicates that the page extends from the base.html file -->
{% extends 'base.html' %}
<! -- Write the title defined in base -->{% endblock title %}<! -- Write the content file defined in base -->
{% block content %}
<! Write an article form -->
<div class="container">
<div class="row">
<div class="col-12">
<br />
<! -- Form for submitting articles -->
<form method="post" action=".">
<! -- Django POST must have cSRF_token -->
{% csrf_token %}
<! -- Article title -->
<div class="form-group">
<! - label - >
<label for="title">The article title</label>
<! -- Textbox -->
<input
type="text"
class="form-control"
id="title"
name="title"
/>
</div>
<! -- Text -->
<div class="form-group">
<label for="body">The article body</label>
<! -- Text area -->
<textarea
type="text"
class="form-control"
id="body"
name="body"
rows="12"
></textarea>
</div>
<! -- Submit button -->
<button type="submit" class="btn btn-primary">complete</button>
</form>
</div>
</div>
</div>
{% endblock content %}
Copy the code
<form>.. </form>
The content of the tag is the form that needs to be submitted.method="post"
Specifies form submission as POST (with view functions)request.method
Be connected withaction="."
Specifies that the address for the form submission is the default current URL.- about
{% csrf_token %}
, which is a network security-related middleware validation in Django. We won’t go into the implementation for now, just know that it must be included in the form or you’ll get a 403 error.<input>
and<textarea>
In the tagname=''
Property specifies the name of the data submitted by the current textbox, whichMust correspond to the field name in the form classOtherwise, the server will not be able to properly match the fields to the data.
Or:
{% csrf_token %}
{% for f in form %}
<div class="col-12 my-2">{{f.label_tag}}</div>
<div class="col-12 my-2">{{f}}</div>
{% endfor %}
Copy the code
Finally, add an article/urls.py URL:
article/urls.py
urlpatterns = [
...
# to write the article
path('article-create/', views.article_create, name='article_create'),]Copy the code
Optimize entry for writing articles
As before, we need a post entry in the navigation bar to optimize the experience. Add the following code to templates/header.html:
<li class="nav-item">
<a class="nav-link" href="{% url 'article:article_create' %}">Write an article</a>
</li>
Copy the code
Save the changes, and run the server entry in the address bar: http://127.0.0.1:8000/article/article-create/, see the following industry: