zoukankan      html  css  js  c++  java
  • Django Form

    案例需求:

    出版社,作者,书籍 后台管理

    from django.db import models
    
    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50)
        city = models.CharField(max_length=60)
        state_province = models.CharField(max_length=30)
        country = models.CharField(max_length=50)
        website = models.URLField()
    
        def __str__(self):
            return self.name
    
    class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=40)
        email = models.EmailField()
    
        def __str__(self):
            return '%s %s' % (self.first_name, self.last_name)
    
    class Book(models.Model):
        title = models.CharField(max_length=100)
        authors = models.ManyToManyField('Author')
        publisher = models.ForeignKey('Publisher')
        publication_date = models.DateField()
    
        def __str(self):
            return self.title
    # books/templates/books/publisher_add.html
    <form method="post">
    {% csrf_token %}
    <p style="color: red">{{ error_message }}</p>
    <label for="name">Name: </label><input id="name" name="name" type="text"/><br/>
    <label for="address">Address: </label><input id="address" name="address" type="text"/><br/>
    <label for="city">City: </label><input id="city" name="city" type="text"/><br/>
    <label for="state_province">State_province: </label><input id="state_province" name="state_province" type="text"/><br/>
    <label for="country">Country: </label><input id="country" name="country" type="text"/><br/>
    <label for="website">Website: </label><input id="website" name="website" type="text"/><br/>
    <input type="submit" value="Submit"/>
    </form>
    
    # books/views.py
    def publisher_add(request):
        if request.method == "POST":
            name = request.POST.get('name', '')
            address = request.POST.get('address', '')
            city = request.POST.get('city', '')
            state_province = request.POST.get('state_province', '')
            country = request.POST.get('country', '')
            website = request.POST.get('website', '')
    
            error_message = []
            if not name:
                error_message.append('Name is required')
            if len(name) > 30:
                error_message.append('Name should be shorter than 30')
    
            if not address:
                error_message.append('Address ia required')
            if len(address) > 50:
                error_message.append('Address should be shorter than 50')
    
            if error_message:
                return render(request, 'books/publisher_add.html', {'error_message': error_message})
            else:
                return HttpResponse('添加成功')
        else:
            return render(request, 'books/publisher_add.html')

    分析:

    • 验证用户输入

    • 返回用户error

    • html构造form

    • 验证用户输入和model的约束重复

    • 代码冗长

    用Django Form来解决这些问题:

    先了解Django Form组件常见用法,models.Model是转换为sql语句,那forms.Form是做什么的呢

     

    说明:

    • class NameForm(forms.Form),自定义Form类

    • form = NameForm(),实例化定义From类

    • form.is_bound,定义Form时是否传入数据,如form=NameForm() 为False;form=NameForm({'key':'value'})为True

    • from.as_p(),form.as_table(),form.as_ul,from对象可以转换为html标签

    • form.is_valid(),验证输入数据合法性

    • form.cleaned_data['key'],必须先执行is_valid(),输入合法后会转换为Python合适的数据类型,并以字典分装

    • from.errors,输入不合法

    需求实现:

    # forms.py
    from django import forms
    class PublisherForm(forms.Form):
        name = forms.CharField(label='Your name', max_length=30)
        address = forms.CharField(max_length=50)
        city = forms.CharField(max_length=60)
        state_province = forms.CharField(max_length=30)
        country = forms.CharField(max_length=50)
        website = forms.CharField(max_length=50)
    
    # views.py
    from django.shortcuts import render, redirect
    from django.http import HttpResponse, HttpResponseRedirect
    from .forms import PublisherForm
    from .models import Publisher
    def publisher_add(request):
        if request.method == "POST":
            form = PublisherForm(request.POST)  # 用户数据获取
            if form.is_valid():  # 用户数据校验
                publisher = Publisher(
                    name=form.cleaned_data['name'],
                    address=form.cleaned_data['address'],
                    city=form.cleaned_data['city'],
                    state_province=form.cleaned_data['state_province'],
                    country=form.cleaned_data['country'],
                    website=form.cleaned_data['website'],
                )
                publisher.save()
                return HttpResponse('添加成功')
            else:
                return render(request, 'books/publisher_add.html', {'form': form})
        else:
            form = PublisherForm()
            return render(request, 'books/publisher_add.html', {'form': form})
    
    # books/publisher_add.html
    <form method="post">
    <h1>添加出版社</h1>
    {{ form }}
    {% csrf_token %}
    <input type="submit" value="提交"/>
    </form>

    Form解决的问题:

    • 用户的输入不用手动获取

    • 用户输入的验证自动完成

    • 表单编写不用手写html

    带来或未解决问题:

    • 需要编写Form结构(和models重复)

    • 需要手动获取内容保存到数据库

    再来一个案例:

    前端模板可以整体使用 {{ form }},也可以单独使用 { form.field.相关属性}}

    # forms.py
    from django import forms
    
    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100,help_text='dadada')
        message = forms.CharField(widget=forms.Textarea)
        sender = forms.EmailField()
        cc_myself = forms.BooleanField(required=False)
    
    # views.py
    def sendmail(request):
        print(request.method)
        if request.method == "POST":
            print('**********')
            form = ContactForm(request.POST)
            if form.is_valid():
                subject = form.cleaned_data['subject']
                message = form.cleaned_data['message']
                sender = form.cleaned_data['sender']
                cc_myself = form.cleaned_data['cc_myself']
    
                recipients = ['nin@jianxin.com.cn']
                if cc_myself:
                    recipients.append(sender)
                # send_mail()
                return HttpResponse('发送成功')
            else:
                return render(request, 'books/sendmail_manual.html',{'form':form})
    
        elif request.method == "GET":
            form = ContactForm()
            return render(request, 'books/sendmail_manual.html', {'form': form})
    
    # books/templates/sendmail_manual.html
    <form method="post" action="{% url 'books:sendmail' %}">
        {% csrf_token %}
        {{ form.non_field_errors }}
        <div>
            {{ form.subject.errors }}
            <label for="{{ form.subject.id_for_label }}">Email Subject: </label>{{ form.subject }}<br/>
            <div>
            <strong>form.subject.label---></strong>{{ form.subject.label }}<br/>
            <strong>form.subject.label_tag---></strong>{{ form.subject.label_tag }}<br/>
            <strong>form.subject.id_for_label---></strong>{{ form.subject.id_for_label }}<br/>
            <strong>form.subject.value---></strong>{{ form.subject.value }}<br/>
            <strong>form.subject.html_name---></strong>{{ form.subject.html_name }}<br/>
            <strong>form.subject.help_text---></strong>{{ form.subject.help_text }}<br/>
            <strong>form.subject.errors---> </strong>{{ form.subject.errors }}<br/>
            </div>
        </div>
        <div>
            {{ form.message.errors }}
            <label for="{{ form.message.id_for_label }}">Your message: </label>
            {{ form.message }}
        </div>
        <div>
            {{ form.sender.errors }}
            <label for="{{ form.sender.id_for_label }}">Your Email Address: </label>
            {{ form.sender }}
        </div>
        <div>
            {{ form.cc_myself.errors }}
            <label for="{{ form.cc_myself.id_for_label }}">CC yourself?: </label>
            {{ form.cc_myself }}
        </div>
        <div>
            <input type="submit" value="Submit"/>
        </div>
    </form>

    说明:

    • forms.EmailField(),前端输入字符串必须符合email格式

    • forms.CharField(widget=forms.Textarea),widget用处很大

    • forms.BooleanField(required=False),转换为type='radio',required=False 可选

    form和field的一些属性

    • {{ form.non_field_errors }} 对应的是 ModelForm联合验证方法 def clean()

    • {{ form.errors }}

    • {{ field.label }}

    • {{ field.label_tag }}

    • {{ field.id_for_label }}

    • {{ field.value }}

    • {{ field.html }}

    • {{ field.help_text}}

    • {{ field.errors}}

    https://docs.djangoproject.com/en/1.11/topics/forms/#looping-over-the-form-s-fields

     

    field 手动校验:

    内置 form field 和widgets:

    时常浏览

    https://docs.djangoproject.com/en/1.11/ref/forms/fields/

    https://docs.djangoproject.com/en/1.11/ref/forms/widgets/

  • 相关阅读:
    自然语言处理一些读书笔记和自己的思考。
    文本情感分析的基础在于自然语言处理、情感词典、机器学习方法等内容。以下是我总结的一些资源。
    自然语言处理哪家强?
    2016,2017中国高考状元调查报告 教师公务员家庭最盛产状元
    书籍装帧知识: 封面 封里 封底 书脊 书冠 书脚 扉页 插页 篇章页目录 版权页 索引 版式 版心 版口 超版口 直(竖)排本 横排本 刊头 破栏 天头 地脚 暗页码 页 另页起 另面起 表注 图注 背题
    How to intercept any postback in a page?
    HearthBuddy卡组
    Button.OnClientClick
    Async Task Types in C#
    ILSpy C# language support status
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/7504274.html
Copyright © 2011-2022 走看看