• Django之form总结


    复习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>
  • 相关阅读:
    TCP 协议如何解决粘包、半包问题 转载:https://mp.weixin.qq.com/s/XqGCaX94hCvrYI_Tvfq_yQ
    [国家集训队]happiness
    CF592D Super M
    [APIO2010]巡逻
    [NOI2012]美食节
    [JSOI2008]Blue Mary的旅行
    [十二省联考2019]D1T2字符串问题
    [十二省联考2019]D2T2春节十二响
    [十二省联考2019]D1T1异或粽子
    [WC2008]游览计划
  • 原文地址:https://www.cnblogs.com/hxf175336/p/9839342.html
Copyright © 2020-2023  润新知