zoukankan      html  css  js  c++  java
  • Django

    一、原生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
    models.py

    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)
    admin.py

    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),
    
    ]
    urls.py
    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())
    views.py
    <!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>
    books.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>
    add.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>
    edit.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())
    views.py
    <!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>
    add.html / edit.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>
    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>
    edit.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})
    扩展 modelform

    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)
  • 相关阅读:
    原生态Vim使用快捷键
    Django 搭建博客记(二)
    Django搭建博客记(一)
    草稿
    骨骼动画的实现(OpenGL实现)
    场景内容的再现
    实现Ogre的脚本分离
    Bullet物理引擎在OpenGL中的应用
    linux fork进程请谨慎多个进程/线程共享一个 socket连接,会出现多个进程响应串联的情况。
    多开发机别名跳转脚本片段
  • 原文地址:https://www.cnblogs.com/alice-bj/p/9183509.html
Copyright © 2011-2022 走看看