Django之form总结

Posted on 2018-10-23 21:01  时光top  阅读(203)  评论(0编辑  收藏  举报

复习Django项目结构:

主要的文件:manage.py,url.py,views.py,settings.py,models.py

  manage.py:项目管理文件,一般不做修改。

  url.py:路由系统,配置views.py中函数和对应路径的关系。

  views.py:添加视图函数,常见的增删查改函数。

  settings.py:模板配置文件,对TEMPLATES 、DATABASES、STATIC_URL 等进行配置。

  models.py:数据库相关表的类描述。

Django基础必备三件套:HttpResponse, render, redirect

  from django.shortcuts import HttpResponse, render, redirect

  HttpResponse:内部传入一个字符串参数,返回给浏览器。

  render:除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。将数据填充进模板文件,最后把结果返回给浏览器。

  redirect:接受一个URL参数,表示跳转到指定的URL。

参考链接:https://www.cnblogs.com/hxf175336/p/9332409.html

     https://www.cnblogs.com/hxf175336/p/9449771.html

表单的处理方式:

常见的三种方式:原生form、form组件、ModelForm组件,以Book表的add为例子分别说明一下这三种方式。

原生form方式:

url.py的代码如下:

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),
]

models.py的代码如下:

from django.db import models

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")
    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

views.py的代码如下小:

from django.shortcuts import render,redirect

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())
add.html中的内容如下:
<!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>

form组件方式:

url.py和models.py的内容不变,和上一种方式一样。

views.py中多一个form组件类BookForm,通过该类拿到form对象,代码如下:

from django.shortcuts import render,redirect

# Create your views here.

from .models import *

from django import forms
from django.forms import widgets #导入表单装饰器组件

#form组件类
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):
    if request.method=="POST":
        form = BookForm(request.POST) #拿到form对象

        if form.is_valid():

            print("cleaned_data",form.cleaned_data)
            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_obj=Book.objects.create(title=title,price=price,date=date,publish=publish)
            book_obj.authors.add(*authors)

            return redirect("/books/")

    form=BookForm()
    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()

    form=BookForm()
    return render(request,"edit.html",locals())

 

 add.html的内容如下:

<!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 }}
        </div>
    {% endfor %}
    <!--一种表单渲染方式,这种方式相同内容太多
    <div>
        {{form.title.label }}
        {{ form.title }}
    </div>

    <div>
        {{form.price.label }}
        {{ form.price }}
    </div>

    <div>
        {{form.date.label }}
        {{ form.date }}
    </div>

    <div>
        {{form.publish.label }}
        {{ form.publish }}
    </div>

    <div>
        {{form.authors.label }}
        {{ form.authors }}
    </div>
    -->
    <input type="submit">
</form>
</body>
</html>

 ModelForm组件方式:

url.py和models.py的内容不变,和之前的方式一样。

views.py直接调用ModelForm中间件,代码如下:

from django.shortcuts import render,redirect

# Create your views here.

from .models import *

from django.forms import ModelForm
from django.forms import widgets #导入表单装饰器组件



'''
# 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")
#     authors=models.ManyToManyField("Author")
#     def __str__(self):
#         return self.title

#form组件类是根据Book类来设计的
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())

'''
from django.forms import widgets as wid
class BookForm(ModelForm):
    class Meta:
        model=Book
        fields="__all__"
        #fields=["title","price"]

        labels={
            "title":"书籍名称",
            "price":"价格",
            "date":"日期",
            "publish":"出版社",
            "authors":"作者",
        }
        widgets={
            "title":wid.TextInput(attrs={"class":"form-control"}),
            "price": wid.TextInput(attrs={"class": "form-control"}),
            "date": wid.Select(attrs={"class": "form-control","type":"date"}),
            "authors": wid.SelectMultiple(attrs={"class": "form-control"}),
        }
        error_messages={
            "title":{"required":"不能为空"}
        }

#查询
def books(request):
    book_list=Book.objects.all()
    return render(request,"books.html",locals())

#添加
def addbook(request):
    if request.method=="POST":#提交数据
        form=BookForm(request.POST)
        if form.is_valid():
            form.save()  #form.model.objects.create(request.POST)
            return redirect("/books/")
        else:
            return render(request, "add.html", locals())

    form=BookForm()
    return render(request,"add.html",locals())

#编辑
def editbook(request,edit_book_id):
    edit_book = Book.objects.filter(pk=edit_book_id).first()
    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/")

    form=BookForm(instance=edit_book)
    return render(request,"edit.html",locals())

 

由于html文件中的重复代码比较多,就写一个form.html文件,其他html文件可以直接调用。

form.html文件的内容如下:

<form action="" method="post" novalidate>
      {% csrf_token %}
      {% for field in form %}
        <div>
         {{ field.label }}
         {{ field }}
        </div>
      {% endfor %}
    <input type="submit">
</form>

 

add.html文件的内容:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!--最新版本的Bookstrap核心CSS文件,使样式好看点-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>
<h3>添加页面</h3>
<div class="row">
    <div class="col-lg-4 col-md-offset-3">
        {% include 'form.html' %}<!--直接引用form.html文件内容,就能不需要重复写了-->
    </div>
</div>

</body>
</html>

 

Copyright © 2024 时光top
Powered by .NET 8.0 on Kubernetes