Django学习【第13篇】:Django之Form组件

1、model经常使用操做html

  一、13个API查询:all,filter,get ,values,values_list,distinct,order_by ,reverse , exclude(排除),count,first,last,esits(判断是否存在)正则表达式

  须要掌握的all、values、values_list的区别数据库

    all:打印的是一个QuerySet集合,一个列表里面放的对象django

    values :是一个字典形式浏览器

    values_list:是一个元组形式  服务器

  all的性能是最低的session

  二、only和deferapp

复制代码
datalist = models.Userinfo.objects.all().only("name","email")  #拿到的仍是一个QuerySet集合,仅仅取name和email
for item in datalist:
    print(item.id) print(item.name) print(item.pwd) #只要表里有这个字段,同样会取到值,额外的会再发一次请求  datalist = models.Userinfo.objects.all().defer("name","email") #阻止,不取name和email for item in datalist: print(item.id) print(item.pwd)
复制代码

  注意:用only的话就去取only里面的字段,取其余的字段效率过低了,尽量的少的链接数据库post

  三、路由系统性能

  反向生成URL:

    有两种方式:{% url "a1" %}

          reverse("a1")

用reverse须要导入     from django.core.urlresolvers import reverse

复制代码
/index/     func    name=a1
    {% url "a1"} reverse('a1') /index/(\d+)/ func name=a2 {% url "a2" 11 %} reverse('a2',args=(11,)) /index/(?P<nid>\d+)/ func name=a3 {% url "a2" nid=11 %} reverse('a3',kwargs={'nid':11})
复制代码

 

 四、Django的生命周期

               Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)

    一、首先走wsgi模块,这个模块也是一个协议,包括wsgiref和uwsgi。

    二、而后路由分配-------views视图

    三、从数据库取数据-----------渲染到html

    注意若是导入js文件,是不会渲染的。

  五、HTTP协议

    详见下一篇博客                                                                                                

2、Form组件

1、Form组件介绍

Form组件能够作的几件事情:

  一、用户请求数据验证

  二、自动生成错误信息    

  三、打包用户提交的正确信息

  四、若是其中有一个错误了,其余的正确这,保留上次输入的内容

  四、自动建立input标签并能够设置样式

2、Form组件的使用

  一、建立规则

class Foo(Form): #必须继承
    username = xxx
    password = xxx email = xxx 注意这里的字段必须和input的name字段一致

 

  二、数据和规则进行匹配

先导入view.py

from django.forms import Form
from django.forms import fields from django.forms import widgets

 

复制代码
from django.shortcuts import render,redirect
from app01 import models # Create your views here. from django.forms import Form from django.forms import fields from django.forms import widgets # 一、建立规则 class TeacherForm(Form): #必须继承Form # 建立字段,本质上是正则表达式 username = fields.CharField( required=True, #必填字段 error_messages={"required":"用户名不能为空!!"}, #显示中文错误提示 widget=widgets.TextInput(attrs={"placeholder":"用户名","class":"form-control"}) #自动生成input框  ) password = fields.CharField(required=True, error_messages={'required': '密码不能为空'}, widget=widgets.TextInput(attrs={'placeholder': '密码', 'class': 'form-control'})) # 不能为空 email = fields.EmailField( required=True, error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"}, widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"}) # 自动生成input框 ) #不能为空且邮箱格式要一致 # 二、使用规则:将数据和规则进行匹配 def teacherindex(request): teacher_obj = models.UserInfo.objects.all() # print(teacher_obj) return render(request,"teacherindex.html",{"teacher_obj":teacher_obj}) def add(request): if request.method=="GET": form = TeacherForm() #只是让显示一个input框 return render(request,"add.html",{"form":form }) else: form = TeacherForm(data=request.POST) # print(form) #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> if form.is_valid():# 开始验证 # print('执行成功',form.cleaned_data) # 全部匹配成功,字典 # {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1} form.cleaned_data['ut_id'] = 1 #要分的清是班主任仍是讲师 models.UserInfo.objects.all().create(**form.cleaned_data) return redirect("/teacherindex/") else: # print("=====?",form.errors,type(form.errors))#返回失败的结果 # print(form.errors["username"][0]) #拿到返回失败的结果,渲染到页面 return render(request,"add.html",{"form":form})
复制代码

 

html.py

复制代码
{% block right %}
    <h1>添加老师信息</h1>
    <hr>
    <form method="post" novalidate> {% csrf_token %} <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }} <p>密码:{{ form.password }}</p>{{ form.errors.password.0 }} <p>邮箱:{{ form.email }}</p>{{ form.errors.email.0 }} <p><input type="submit" value="提交"></p> </form> {% endblock %}
复制代码

若是访问视图的是一个GET 请求,它将建立一个空的表单实例并将它放置到要渲染的模板的上下文中。这是咱们在第一个访问该URL 时预期发生的状况。

若是表单的提交使用POST 请求,那么视图将再次建立一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫作”绑定数据至表单“(它如今是一个绑定的表单)。

咱们调用表单的is_valid()方法;若是它不为True,咱们将带着这个表单返回到模板。这时表单再也不为空(未绑定),因此HTML 表单将用以前提交的数据填充,而后能够根据要求编辑并改正它。

若是is_valid()True,咱们将可以在cleaned_data 属性中找到全部合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向以前,咱们能够用这个数据来更新数据库或者作其它处理。

注意: form = TeacherForm()  #没有参数,只是一个input框

    form = TeacherForm(data=request.POST) # 数据和规则放置一块儿 (添加的时候用)

    form = TeacherForm(initial={'username':obj.username,'password':obj.password,'email':obj.email})   # 显示input,而且将数据库中的默认值填写到input框中 (编辑的时候用)

 

Widgets

每一个表单字段都有一个对应的Widget 类,它对应一个HTML 表单Widget,例如<input type="text">

在大部分状况下,字段都具备一个合理的默认Widget。例如,默认状况下,CharField 具备一个TextInput Widget,它在HTML 中生成一个<input type="text">

字段的数据

无论表单提交的是什么数据,一旦经过调用is_valid() 成功验证(is_valid() 返回True),验证后的表单数据将位于form.cleaned_data 字典中。这些数据已经为你转换好为Python 的类型。

注:此时,你依然能够从request.POST 中直接访问到未验证的数据,可是访问验证后的数据更好一些。

在上面的联系表单示例中,is_married将是一个布尔值。相似地,IntegerField 和FloatField 字段分别将值转换为Python 的int 和float

3、数据库表设计

设计表时注意的几点:

  一、 nid = models.AutoField(primary_key=True)        #若是不指定django会默认加上id的

    nid = models.BigAutoField(primary_key=True)   #但那些整型知足不了你的时候,就用BigAutoField

  二、对于类的注释通常加在类里面

  三、verbose_name=“标题”   字段的中文提示

  四、ForeignKey(to = "表名",tofield= "字段")    #这两个to能够不用写,可是关联的表名必定要写

  五、releated_name = "uuu"   反向查询。若是一个表中有多个ManyTwoMany()或者ForeignKey()必须加上releated_name 

  六、字段常常变更的适合连表

     字段变化小,不怎么变的适合在一个表中,不进行连表:就用choices

       吧班主任和老师能够放到一个表中、由于他们有相同的属性,若是属性全是同样的,能够放在一个表里(推荐)

     也能够分开放,老师表是老师表,班主任表是班主任表。这样就会进行连表操做,连表有性能消耗。

举例:文章和文章类型

   分析:一个文章有一个类型,一个类型能够对应多个文章(因此文章和文章类型是一对多的关系,关联字段要放在多的一方)

  一:连表设计:

复制代码
class News(models.Model):
    title = models.CharField(max_length=32) summary = models.CharField(max_length=255) news_type = models.ForeignKey(to="NewsType") class NewsType(models.Model): type_title = models.CharField(max_length=32)

News:

  id   title   summary  news_type_id
  1    t....    科技...     2
  2    t....    科技...     1
  3    t....    科技...     2

NewsType:
 id title

  1      图片
  2      挨踢1024
  3      段子

 

# 查看全部新闻
new_list = models.News.objects.all()
for row in new_list:
print(row.title,row.summary,row.news_type.title)

 

复制代码

  二 :放在一个表中的操做:choices

复制代码
class News2(models.Model):
    title = models.CharField(max_length=32) summary = models.CharField(max_length=255) news_type_chices = ( (1, '图片'), (4, '挨踢1024'), (3, '段子'), ) news_type = models.IntegerField(choices=news_type_chices)

# 查看全部新闻
new_list = News.objects.all()
for row in new_list:
print(row.title,row.summary, row.get_news_type_display() )

复制代码

举例二:用户和用户类型

  一:连表设计

复制代码
class UserType(models.Model):
        """
        用户类型表,个数常常变更
        """ title = models.CharField(max_length=32) class UserInfo(models.Model): """ 用户表:讲师和班主任 """ username = models.CharField(max_length=32) password = models.CharField(max_length=64) email = models.CharField(max_length=32) ut = models.ForeignKey(to="UserType")
复制代码

  二:不连表设计:choices

复制代码
class UserInfo(models.Model):
#     """
#     用户表
#     """
    username = models.CharField(max_length=32) password = models.CharField(max_length=64) email = models.CharField(max_length=32,verbose_name="邮箱") user_type_choices = ( (1, '班主任'), (2, '讲师'), ) user_type_id = models.IntegerField(choices=user_type_choices)
复制代码

4、登陆

 可设置一个装饰器

复制代码
def auth(func):
    def inner(request,*args,**kwargs): is_login = request.session.get("is_login", None) if not is_login: return redirect("/login/") ret = func(*args,**kwargs) return ret return inner
复制代码

 须要注意的:  

  一、action不写路径,默认提交到当前 

  二、向后台提交数据用post,获取数据用get

  三、submit通常加上value,有些浏览器可能会不识别

  四、通常配置文件的键都是大写的

相关文章
相关标签/搜索