1.models.py ...
makemigrations
migrate
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)
modelsphp
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(to="Publish",on_delete=True) 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
admin.pycss
from django.contrib import admin # Register your models here. from .models import * admin.site.register(Book) admin.site.register(Author) admin.site.register(Publish)
urlshtml
"""formsDemo URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^books/', views.books), url(r'^book/add', views.addbook), url(r'^book/edit/(\d+)', views.editbook), ]
views前端
from django.shortcuts import render,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") author_pk_list=request.POST.getlist("author_pk_list") # [1,2] book_obj=Book.objects.create(title=title,price=price,date=date,publish_id=publish_id) book_obj.authors.add(*author_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") author_pk_list=request.POST.getlist("author_pk_list") # [1,2] Book.objects.filter(pk=edit_book_id).update(title=title,price=price,date=date,publish_id=publish_id) book_obj=Book.objects.filter(pk=edit_book_id).first() book_obj.authors.set(author_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())
books.htmlpython
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </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>{{ book.authors.all }}</td> <td><a href="/book/edit/{{book.pk}}"><button>編輯</button></a></td> </tr> {% endfor %} </table> </body> </html>
add.htmlgit
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </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="author_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>
edit.htmlweb
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </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="author_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>
forms組件1: https://www.cnblogs.com/venicid/p/9308074.html正則表達式
https://www.cnblogs.com/yuanchenqi/articles/7614921.html
https://www.cnblogs.com/wupeiqi/articles/6144178.html數據庫
form組件1:forms組件添加,編輯用原生form表單apache
form組件2:實現了編輯也用form表單
ChoiceField(Field)
ModelChoiceField(ChoiceField)
ModelMultipleChoiceField(ModelChoiceField)
form組件能作的事情:
1.能渲染頁面
2.能作校驗用
3.拿到錯誤信息顯示
views
from django.shortcuts import render,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="書籍名稱") price = forms.DecimalField(max_digits=8, decimal_places=2,label="價格") # 999999.99 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","title")) publish=forms.ModelChoiceField(queryset=Publish.objects.all()) authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all()) 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/') print(form) 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") # [1,2] 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())
add
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </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>
edit
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </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>
一、Django內置字段以下:
Field required=True, 是否容許爲空 widget=None, HTML插件 label=None, 用於生成Label標籤或顯示內容 initial=None, 初始值 help_text='', 幫助信息(在標籤旁邊顯示) error_messages=None, 錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'} show_hidden_initial=False, 是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直) validators=[], 自定義驗證規則 localize=False, 是否支持本地化 disabled=False, 是否能夠編輯 label_suffix=None Label內容後綴 CharField(Field) max_length=None, 最大長度 min_length=None, 最小長度 strip=True 是否移除用戶輸入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 總長度 decimal_places=None, 小數位長度 BaseTemporalField(Field) input_formats=None 時間格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 時間間隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定製正則表達式 max_length=None, 最大長度 min_length=None, 最小長度 error_message=None, 忽略,錯誤信息使用 error_messages={'invalid': '...'} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否容許空文件 ImageField(FileField) ... 注:須要PIL模塊,pip3 install Pillow 以上兩個字典使用時,須要注意兩點: - form表單中 enctype="multipart/form-data" - view函數中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 選項,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默認select插件 label=None, Label內容 initial=None, 初始值 help_text='', 幫助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查詢數據庫中的數據 empty_label="---------", # 默認空顯示內容 to_field_name=None, # HTML中value的值對應的字段 limit_choices_to=None # ModelForm中對queryset二次篩選 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 對選中的值進行一次轉換 empty_value= '' 空值的默認值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 對選中的每個值進行一次轉換 empty_value= '' 空值的默認值 ComboField(Field) fields=() 使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 容許文件 allow_folders=False, 容許文件夾 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用 SlugField(CharField) 數字,字母,下劃線,減號(連字符) ... UUIDField(CharField) uuid類型 ...
二、Django內置插件:
TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
三、經常使用選擇插件:
# 單radio,值爲字符串 # user = fields.CharField( # initial=2, # widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) # ) # 單radio,值爲字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.RadioSelect # ) # 單select,值爲字符串 # user = fields.CharField( # initial=2, # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) # ) # 單select,值爲字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.Select # ) # 多選select,值爲列表 # user = fields.MultipleChoiceField( # choices=((1,'上海'),(2,'北京'),), # initial=[1,], # widget=widgets.SelectMultiple # ) # 單checkbox # user = fields.CharField( # widget=widgets.CheckboxInput() # ) # 多選checkbox,值爲列表 # user = fields.MultipleChoiceField( # initial=[2, ], # choices=((1, '上海'), (2, '北京'),), # widget=widgets.CheckboxSelectMultiple # )
https://www.cnblogs.com/yuanchenqi/articles/7614921.html
https://www.cnblogs.com/yuanchenqi/articles/8034442.html
1.modelform 組件
中間轉換的組件, 不用本身去寫form組件。
將模型錶轉換成, 具體的form組件。
2.fields
https://www.cnblogs.com/yuanchenqi/articles/8034442.html
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}) 擴展 modelform
models.CharFiled()
models.EmailField() # 爲何,不寫charField? 由於在使用 modelForm 時,能夠校驗!!這時EmailField纔有意義!
eg:
models.URLField
models.UUIDField
views
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())
add.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> add.html
edit
<!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 %} <p> {{ field.label }} {{ field }} <small><span class="pull-right text-danger has-error">{{ field.errors.0 }}</span></small> </p> {% endfor %} <input type="submit"> </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)
WSGI(Web Server Common Interface)是專門爲Python語言制定的web服務器與應用程序之間的網關接口規範,通俗的來講,只要一個服務器擁有一個實現了WSGI標準規範的模塊(例如apache的mod_wsgi模塊),那麼任意的實現了WSGI規範的應用程序都能與它進行交互。所以,WSGI也主要分爲兩個程序部分:服務器部分和應用程序部分。
wsgiref則是官方給出的一個實現了WSGI標準用於演示用的簡單Python內置庫,它實現了一個簡單的WSGI Server和WSGI Application(在simple_server模塊中),主要分爲五個模塊:simple_server, util, headers, handlers, validate。
wsgiref源碼地址:https://pypi.python.org/pypi/wsgiref