一、原生form
https://www.cnblogs.com/yuanchenqi/articles/7614921.html
案例:
步骤:
1.models.py ...
makemigrations
migrate
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2) # 999999.99
date = models.DateField()
publish = models.ForeignKey("Publish",on_delete=models.CASCADE)
authors = models.ManyToManyField("Author")
def __str__(self):
return self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name
2.admin.py
from django.contrib import admin
# Register your models here.
from .models import *
admin.site.register(Book)
admin.site.register(Publish)
admin.site.register(Author)
3.createsuperuser
yuan yuan1234
1.addbook:(getlist)
...
publish_id = request.POST.get('publish_id')
auhtor_pk_list = request.POST.getlist('auhtor_pk_list') # ['1', '2']
book_obj = Book.objects.create(title=title,price=price,date=date,publish_id=publish_id)
book_obj.authors.add(*auhtor_pk_list)
2.editbook:(set)
...
<p>价格 <input type="text" name="price" value="{{ edit_book.price }}"></p>
{% if author in edit_book.authors.all %}
<option selected value="{{ author.pk }}">{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
...
ret = Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish_id=publish_id)
print('ret---', ret) # 1
book_obj = Book.objects.filter(pk=edit_book_id).first()
print('book_obj---', book_obj) # 对象
book_obj.authors.set(auhtor_pk_list)
4.code
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('books/', views.books),
path('book/add/', views.addbook),
re_path('book/edit/(\d+)', views.editbook),
]
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from .models import *
def books(request):
book_list = Book.objects.all()
return render(request,'books.html',locals())
def addbook(request):
if request.method == 'POST':
title = request.POST.get('title')
price = request.POST.get('price')
date = request.POST.get('date')
publish_id = request.POST.get('publish_id')
auhtor_pk_list = request.POST.getlist('auhtor_pk_list') # ['1', '2']
print(auhtor_pk_list)
book_obj = Book.objects.create(title=title,price=price,date=date,publish_id=publish_id)
book_obj.authors.add(*auhtor_pk_list)
return redirect('/books/')
publish_list = Publish.objects.all()
author_list= Author.objects.all()
return render(request,'add.html',locals())
def editbook(request, edit_book_id):
if request.method == 'POST':
title = request.POST.get('title')
price = request.POST.get('price')
date = request.POST.get('date')
publish_id = request.POST.get('publish_id')
auhtor_pk_list = request.POST.getlist('auhtor_pk_list') # ['1', '2']
print(auhtor_pk_list)
ret = Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish_id=publish_id)
print('ret---', ret) # 1
book_obj = Book.objects.filter(pk=edit_book_id).first()
print('book_obj---', book_obj) # 对象
book_obj.authors.set(auhtor_pk_list)
return redirect('/books/')
edit_book = Book.objects.filter(pk=edit_book_id).first()
publish_list = Publish.objects.all()
author_list = Author.objects.all()
return render(request, 'edit.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>books</title>
</head>
<body>
<a href="/book/add/"><button>添加书籍</button></a>
<hr>
<table border="1">
{% for book in book_list %}
<tr>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.date|date:'Y-m-d' }}</td>
<td>{{ book.publish.name}}</td>
<td>
{% for author in book.authors.all %}
{{ author.name }}
{% endfor %}
</td>
<td><a href="/book/edit/{{ book.pk }}">编辑</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>添加页面</h3>
<form action="" method="post">
{% csrf_token %}
<p>书籍名称 <input type="text" name="title"></p>
<p>价格 <input type="text" name="price"></p>
<p>日期 <input type="date" name="date"></p>
<p>出版社
<select name="publish_id" id="">
{% for publish in publish_list %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %}
</select>
</p>
<p>作者
<select name="auhtor_pk_list" id="" multiple>
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %}
</select>
</p>
<input type="submit">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>编辑页面</h3>
<form action="" method="post">
{% csrf_token %}
<p>书籍名称 <input type="text" name="title" value="{{ edit_book.title}}"></p>
<p>价格 <input type="text" name="price" value="{{ edit_book.price }}"></p>
<p>日期 <input type="date" name="date" value="{{ edit_book.date|date:'Y-m-d' }}"></p>
<p>出版社
<select name="publish_id" id="">
{% for publish in publish_list %}
{% if edit_book.publish == publish %}
<option selected value="{{ publish.pk }}">{{ publish.name }}</option>
{% else %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<p>作者
<select name="auhtor_pk_list" id="" multiple>
{% for author in author_list %}
{% if author in edit_book.authors.all %}
<option selected value="{{ author.pk }}">{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<input type="submit">
</form>
</body>
</html>
二、form组件
https://www.cnblogs.com/yuanchenqi/articles/7614921.html
https://www.cnblogs.com/wupeiqi/articles/6144178.html
针对form表单设计form组件
ChoiceField(Field)
ModelChoiceField(ChoiceField)
ModelMultipleChoiceField(ModelChoiceField)
添加,编辑,用form组件!
from django import forms
from django.forms import widgets
class BookForm(forms.Form):
title = forms.CharField(max_length=32,label='书籍名称',
error_messages={'required':'不能为空'},
)
price = forms.DecimalField(max_digits=8,decimal_places=2,label='价格')
date = forms.DateField(label='日期',
widget=widgets.TextInput(attrs={'type':'date'})
)
# gender = forms.ChoiceField(choices=((1,'男'),(2,'女'),(3,'其他'))) # 与sql没关系
# publish = forms.ChoiceField(choices=Publish.objects.all().values_list('pk','name'))
publish = forms.ModelChoiceField(queryset=Publish.objects.all(),label='出版社')
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all(),label='作者')
注意点:
1.
book_obj = Book.objects.create(title=title,price=price,date=date,publish=publish)
book_obj.authors.add(*authors)
2.
edit_book = Book.objects.filter(pk=edit_book_id).first()
form = BookForm(initial={"title":edit_book.title,"price":edit_book.price,
"date":edit_book.date,"publish":edit_book.publish,
'authors':edit_book.authors.all()})
3.
Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish=publish)
book_obj = Book.objects.filter(pk=edit_book_id).first()
book_obj.authors.set(authors)
4.
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label }}
{{ field }}
{{ field.errors.0 }}
</div>
{% endfor %}
<input type="submit">
</form>
form组件能做的事情:
1.能渲染页面
2.能做校验用
3.拿到错误信息显示
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from .models import *
from django import forms
from django.forms import widgets
class BookForm(forms.Form):
title = forms.CharField(max_length=32,label='书籍名称',
error_messages={'required':'不能为空'},
)
price = forms.DecimalField(max_digits=8,decimal_places=2,label='价格')
date = forms.DateField(label='日期',
widget=widgets.TextInput(attrs={'type':'date'})
)
# gender = forms.ChoiceField(choices=((1,'男'),(2,'女'),(3,'其他')))
# publish = forms.ChoiceField(choices=Publish.objects.all().values_list('pk','name'))
publish = forms.ModelChoiceField(queryset=Publish.objects.all(),label='出版社')
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all(),label='作者')
def books(request):
book_list = Book.objects.all()
return render(request,'books.html',locals())
def addbook(request):
form = BookForm()
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
"""
clean_date: {'title': '书1', 'price': Decimal('1111'),
'date': datetime.date(2018, 6, 7),
'publish': <Publish: 香蕉出版社>, # 对象
'authors': <QuerySet [<Author: alex>, <Author: egon>]>}
"""
title = form.cleaned_data.get('title')
price = form.cleaned_data.get('price')
date = form.cleaned_data.get('date')
publish = form.cleaned_data.get('publish')
authors = form.cleaned_data.get('authors')
book_obj = Book.objects.create(title=title,price=price,date=date,publish=publish)
book_obj.authors.add(*authors)
return redirect('/books/')
return render(request,'add.html',locals())
def editbook(request, edit_book_id):
edit_book = Book.objects.filter(pk=edit_book_id).first()
form = BookForm(initial={"title":edit_book.title,"price":edit_book.price,
"date":edit_book.date,"publish":edit_book.publish,
'authors':edit_book.authors.all()})
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
title = form.cleaned_data.get('title')
price = form.cleaned_data.get('price')
date = form.cleaned_data.get('date')
publish = form.cleaned_data.get('publish')
authors = form.cleaned_data.get('authors')
Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish=publish)
book_obj = Book.objects.filter(pk=edit_book_id).first()
book_obj.authors.set(authors)
return redirect('/books/')
return render(request, 'edit.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>添加页面</h3>
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label }}
{{ field }}
{{ field.errors.0 }}
</div>
{% endfor %}
<input type="submit">
</form>
</body>
</html>
-------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>编辑页面</h3>
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label }}
{{ field }}
{{ field.errors.0 }}
</div>
{% endfor %}
<input type="submit">
</form>
</body>
</html>
三、modelform
https://www.cnblogs.com/yuanchenqi/articles/7614921.html
https://www.cnblogs.com/yuanchenqi/articles/8034442.html
注意点:
1.modelform 组件
中间转换的组件, 不用自己去写form组件。
将模型表转换成, 具体的form组件。
2.fields
class BookForm(ModelForm):
class Meta:
model = Book
fields = "__all__" # 对所有字段转换
# fields = ['title','price']
3.一对多,多对多,不用考虑!
form = BookForm(request.POST)
if form.is_valid():
form.save()
return redirect('/books/')
4.BookForm(instance=edit_book) # 接收一个对象
form = BookForm(request.POST,instance=edit_book)
if form.is_valid():
form.save()
return redirect('/books/')
5.create、update
form = BookForm(request.POST) # create
if form.is_valid():
form.save() # form.model.objects.create(request.POST)
form = BookForm(request.POST,instance=edit_book) # update
if form.is_valid():
form.save() # edit_book.update(request.POST)
6.{% include 'form.html' %}
form.html:
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field.label }}
{{ field }}
<small><span class="pull-right text-danger has-error">{{ field.errors.0 }}</span></small>
</div>
{% endfor %}
<input type="submit">
</form>
7.models.py
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2) # 999999.99
date = models.DateField()
publish = models.ForeignKey("Publish",on_delete=models.CASCADE)
authors = models.ManyToManyField("Author")
models.CharFiled()
models.EmailField() # 为什么,不写charField? 因为在使用 modelForm 时,可以校验!!这时EmailField才有意义!
eg:
models.URLField
models.UUIDField
views.py
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from .models import *
from django.forms import ModelForm
from django.forms import widgets as wid # 因为重名,所以起个别名!
wid_text = wid.TextInput(attrs={'class':'form-control'})
required_msg = {'required':'不能为空'}
class BookForm(ModelForm):
class Meta:
model = Book
fields = "__all__" # 对所有字段转换
# fields = ['title','price']
labels = {"title":"书籍名称","price":"价格","date":"日期","publish":"出版社","authors":"作者"}
widgets = {
'title':wid_text,
'price':wid_text,
'date':wid.TextInput(attrs={'class':'form-control','type':'date'}),
'publish':wid.Select(attrs={'class':'form-control'}),
'authors':wid.SelectMultiple(attrs={'class':'form-control'})
}
error_messages = {
'title':required_msg,
'price':required_msg,
'date':{'required':'不能为空','invalid':'格式错误'},
'publish':required_msg,
'authors':required_msg,
}
def books(request):
book_list = Book.objects.all()
return render(request,'books.html',locals())
def addbook(request):
form = BookForm()
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save() # form.model.objects.create(request.POST)
return redirect('/books/')
return render(request,'add.html',locals())
def editbook(request, edit_book_id):
edit_book = Book.objects.filter(pk=edit_book_id).first()
form = BookForm(instance=edit_book)
if request.method == 'POST':
form = BookForm(request.POST,instance=edit_book)
if form.is_valid():
form.save() # edit_book.update(request.POST)
return redirect('/books/')
return render(request, 'edit.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>添加页面</h3>
<div class="row">
<div class="col-md-4 col-md-offset-1">
{% include 'form.html' %}
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>编辑页面</h3>
<div class="row">
<div class="col-md-4 col-md-offset-1">
{% include 'form.html' %}
</div>
</div>
</body>
</html>
form.html
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field.label }}
{{ field }}
<small><span class="pull-right text-danger has-error">{{ field.errors.0 }}</span></small>
</div>
{% endfor %}
<input type="submit">
</form>
from django.shortcuts import render,HttpResponse,redirect
from django.forms import ModelForm
# Create your views here.
from app01 import models
def test(request):
# model_form = models.Student
model_form = models.Student.objects.all()
return render(request,'test.html',{'model_form':model_form})
class StudentList(ModelForm):
class Meta:
model = models.Student #对应的Model中的类
fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
exclude = None #排除的字段
labels = None #提示信息
help_texts = None #帮助提示信息
widgets = None #自定义插件
error_messages = None #自定义错误信息
#error_messages用法:
error_messages = {
'name':{'required':"用户名不能为空",},
'age':{'required':"年龄不能为空",},
}
#widgets用法,比如把输入用户名的input框给为Textarea
#首先得导入模块
from django.forms import widgets as wid #因为重名,所以起个别名
widgets = {
"name":wid.Textarea
}
#labels,自定义在前端显示的名字
labels= {
"name":"用户名"
}
def student(request):
if request.method == 'GET':
student_list = StudentList()
return render(request,'student.html',{'student_list':student_list})
else:
student_list = StudentList(request.POST)
if student_list.is_valid():
student_list.save()
return render(request,'student.html',{'student_list':student_list})
def student_edit(request,pk):
obj = models.Student.objects.filter(pk=pk).first()
if not obj:
return redirect('test')
if request.method == "GET":
student_list = StudentList(instance=obj)
return render(request,'student_edit.html',{'student_list':student_list})
else:
student_list = StudentList(request.POST,instance=obj)
if student_list.is_valid():
student_list.save()
return render(request,'student_edit.html',{'student_list':student_list})
https://www.cnblogs.com/yuanchenqi/articles/8034442.html
四、前端form表单,后台form组件
前端手写一个form表单,后台使用form组件,进行校验,也是可以的!!
注意: <p>名称 <input type="text" name="title"></p> 和 title = forms.CharField()
views.py
from django import forms
class BookForms(forms.Form):
title = forms.CharField()
price = forms.FloatField()
def addbook(request):
form = BookForms()
if request.method == 'POST':
form = BookForms(request.POST)
# form = BookForm({'title':'php','price':111,'xxx':'egon'})
if form.is_valid():
print('clean_data',form.cleaned_data)
# clean_data {'title': '水浒传', 'price': 123.0}
else:
print('error',form.errors)
return render(request,'addbook.html',locals())
addbook.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>添加书籍</h3>
<form action="" method="post" novalidate>
{% csrf_token %}
<p>名称 <input type="text" name="title"></p>
<p>价格 <input type="text" name="price"></p>
<p>xxx <input type="text" name="xxx"></p>
<input type="submit">
</form>
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
{{ form.as_table }}
{{ form.as_ul }}
<input type="submit">
</form>
</body>
</html>
五、补充 - 请求流程
说明:
django 请求流程图--流程最重要!
http协议
请求协议:请求首行,请求头,请求体!
响应协议: 响应首行,响应头,响应体!
我们发给浏览器的响应体(html)是一堆 str 浏览器解析(html)才能看到数据!
render 对templates 模板渲染!
没有模板 就 httpresponse 返回str
打开文件 捕获是否模板语法,嵌入{{}} 数据 返回 html(str) response
只要到了 中间件 交给浏览器的 一定已经是一些 html(str)
来源:oschina
链接:https://my.oschina.net/u/4298485/blog/3937291