Python Web 框架-Django day06

目录

1.Django ORM

2.HttpRequest - 请求

3.使用forms模块处理表单


day05

1.F和Q.

  1. F()
    Author.objects.all().update(age=F('age')+10)
     
  2. Q()
    Q() | Q()
    Author.objects.filter(Q(id=1)|Q(age__gte=35))

2.原生方法

  1. 查询 - raw()

    Entry.objects.raw(sql)
  2. 增删改
    with connection.cursor() as cursor
       cursor.execute(sql)

3.使用后台管理Models

  1. 基本管理
    1. def __str__(self)
    2. 内部类 - Meta
      1. db_table
      2. verbose_name
      3. verbose_name_plural
      4. ordering = []
    3. verbose_name
      name=model.CharField(max_length="",verbose_name)
  2. 高级管理
    1. 管理高级类
      继承自admin.ModelAdmin
      注册高级管理类 : admin.site.register(Entry,EntryAdmin)
    2. 高级管理属性
      1. list_display
      2. list_display_links
      3. list_editable
      4. search_fields
      5. list_filter
      6. date_hierarchy
      7. fields
      8. fieldsets
        fieldsets =(
            #分组1
            ('分组名称',{
                'fields':('属性1','属性2'),
                'classes':('collapse',),
            }),
            #分组2
            ()
            )

4.关系映射

  1. 一对一
    1. 设置一对一
      任何一个实体中:
      属性= models.OneToOneField(Entry)
    2. 反向引用
      属性:对应的实体类名全小写
  2. 一对多
    1. 的多实体中增加对一的引用
      属性= models.ForeignKey(Entry)
    2. 反向引用
      属性:类名全小写_set
  3. 多对多
    1. 设置多对多
      任何一个类中
      属性= models.MantToManyField(Entry)
    2. 反向引用
      属性:类名全小写_set

1.Django ORM

  1. 自定义查询对象 - objects
    Entry.objects.filter()
    1. 声明类EntryManager继承自modelss.Manager
      允许在EntryManager中添加自定义函数

      class EntryManager(models.Manager):
        def 函数名(self,自定义参数列表):
          ... ...
          return ... ...
    2. 使用 EntryManager 覆盖Models类中原有的objects
      class Entry(models.Model):
        objects = EntryManager()
        name = models.CharField(xxx)

      练习:
      为Author 实体自定义 objects对象,增加一个函数,用于查询年龄小于指定年龄值的作者的QuerySet
      解析:
      在index下 model.py
      #自定义AuthorManager类,用于覆盖Author实体类中的objects
      class AuthorManager(models.Manager):
        def age_lt(self,age):
          return self.filter(age__lt=age)
      
      
      class Author(models.Model):
        #使用AuthorManager对象覆盖本类中的objects
        objects = AuthorManager()
        name = models.CharField(max_length=30,verbose_name='姓名')
        age = models.IntegerField(verbose_name='年龄')
        email = models.EmailField(null=True,verbose_name='邮件')
        #表示用户的激活状态:True,表示已激活,False,表示未激活
        #由于是新增列,所以必须要给默认值或允许为空
        #由于BooleanField默认是不允许为空的,所以此处选择了增加默认值
        isActive = models.BooleanField(default=True,verbose_name='激活用户')
        #增加一个字段,表示用户的头像,可以上传的
        picture = models.ImageField(upload_to="static/upload",null=True,verbose_name='头像')
      
      在index下views.py
      def titleCount_views(request):
      
        authors = Author.objects.age_lt(45)
        for author in authors:
          print(author.name,author.age)
        return HttpResponse("Query OK")



       

2.HttpRequest - 请求

  1. 什么是HttpRequest
    HttpRequest,在Django中就是请求对象的封装体现,里面封装了请求过程中的所有信息,在Django中HTTPRequest被封装成了请求对象,被封装到请求处理视图函数中做为参数,在调用视图时自动传入
  2. 的的HTTPRequest中的主要内容
    1. request.scheme:请求协议
    2. request.body:请求主体
    3. request.path : 请求路径(具体资源路径)
    4. request.get_host() : 请求的主机地址 / 域名
    5. request.method:获取请求方法
    6. request.GET : 封装了get请求方式所提交的数据
    7. request.POST:封装了后请求方式所提交的数据
    8. request.COOKIES : 封装了 cookies 中的所有数据
    9. request.META:封装了请求的元数据
      request.META.HTTP_REFERER:封装了请求的源地址
  3. 获取请求提交的数据
    1. get请求方式
      request.GET ['名称']
      request.GET.get ['名称']
      1. 使用表单提交数据
        <form method='get'></form>
      2. 通过地址拼查查询字符串
        <a href="地址?参数1=值1&参数2=值2"></a>

        DJango中通过url传参
          url(r'^xxx/(\d+)')
          该写法属于Django表准并非Http标准,不能用 request.GET[]
    2. post请求方式
      request.POST ['名称']

      CSRF:Cross-Site Request Forgery
                 跨站点       请求       伪装

      解决方案:
      1. 如果想通过CSRF验证,则需要在表单中的第一行增加
        {%csrf_token%}
      2. 取消csrf的验证
        删除settings.py中MIDDLEWARE中
        CsrfViewMiddleware 中间件
      3. 在处理函数上增加装饰器
        @csrf_protect

        @csrf_protect
        def post_views(request):
          xxx

        练习:完成果园注册操作
        1. 创建数据库 - fruit
        2. 创建实体类 -User
          uphone - 手机号
          upwd - 密码
          uname - 用户名
          uemail - 电子邮件
          isActive - 是否激活
        3. 完善注册模板,提交数据库时,数据将保存进数据库

          解析:在指数应用models.py创建实体类


           
          from django.db import models
          
          # Create your models here.
          class User(models.Model):
            uphone=models.CharField(max_length=11)
            upwd=models.CharField(max_length=20)
            uname=models.CharField(max_length=30)
            uemail=models.EmailField()
            isActive=models.BooleanField(default=True)
          
            def __str__(self):
              return self.uname
          
            class Meta:
              db_table = 'user'
          

          在视图views.py保存数据
           

          from django.http import HttpResponse
          from django.shortcuts import render
          from .models import *
          from .forms import *
          
          def register_views(request):
            # 判断是get请求还是post请求,得到用户的请求意图
            if request.method == 'GET':
              return render(request,'register.html')
            else:
              #先验证手机号在数据库中是否存在
              uphone = request.POST['uphone']
              users = User.objects.filter(uphone=uphone)
              if users:
                #uphone 已经存在
                errMsg = '手机号码已经存在'
                return render(request,'register.html',locals())
              #接收数据插入到数据库中
              upwd = request.POST['upwd']
              uname = request.POST['uname']
              uemail = request.POST['uemail']
              user = User()
              user.uphone = uphone
              user.upwd = upwd
              user.uname = uname
              user.uemail = uemail
              user.save()
              return HttpResponse('注册成功')

3.使用forms模块处理表单

  1. forms模块的作用
    通过forms模块,允许将表单与class相结合,允许通过class生成表单
  2. 使用 forms 模块
    1. 创建 forms.py文件
    2. 导入 django 的 forms
      from dhango import forms
    3. 创建 class,一个class 对应生成一个表单
      class ClassName(forms.Form)
        pass
    4. 在 class 中创建属性
      一个属性对应到表单中会生成一个控件

      forms.py
      from django import forms
      
      # 为topic控件初始化数据
      TOPIC_CHOICE = (
        ('1','好评'),
        ('2','中评'),
        ('3','差评'),
      )
      
      #表示评论内容的表单控件们
      #控件1 - 评论标题 - 文本框
      #控件2 - Email - Email框
      #控件3 - 评论内容 - Textarea
      #控件4 - 评论级别 - Select
      #控件5 - 是否保存 - Checkbox
      class RemarkForm(forms.Form):
        # subject - input type='text'
        # label 表示的是控件前的文本
        subject=forms.CharField(label='标题')
        # email - input type='email'
        email = forms.EmailField(label='邮箱')
        # message - Textarea
        # widget=forms.Textarea,表示将当前属性变为多行文本域
        message = forms.CharField(label='内容',widget=forms.Textarea)
        # topic - Select
        topic = forms.ChoiceField(label='级别',choices=TOPIC_CHOICE)
        # isSaved - checkbox
        isSaved = forms.BooleanField(label='是否保存')
  3. 在模板中解析 form 对象
    1. 注意
      1. 需要自定义 <form>
      2. 需要自定义按钮
    2. 处理方法
      在视图中创建 form 的对象,并发送到模板中
      ex:
        form = RemarkForm()
        return render(request,'xxx.html',locals())

      index应用下的views.py
      def form_views(request):
        if request.method == 'GET':
          form = RemarkForm()
          return render(request,'04-form.html',locals())
        else:
          # subject = request.POST['subject']
          # email = request.POST['email']
          # message = request.POST['message']
          # topic = request.POST['topic']
          # isSaved = request.POST['isSaved']
          # print(subject,email,message,topic,isSaved)
      
          # 通过RemarkForm自动接收数据
          # 1.将request.POST数据传递给RemarkForm构造器
          form = RemarkForm(request.POST)
          # 2.验证form对象
          if form.is_valid():
            # 3.通过验证后获取具体的数据
            cd = form.cleaned_data
            subject = cd['subject']
            email = cd['email']
            isSaved = cd['isSaved']
            message = cd['message']
            topic = cd['topic']
            print(subject,email,isSaved,message,topic)
          return HttpResponse('Post OK')
      


      在模板中解析 form 对象
      1. 手动解析
        在模板中
          {% for field in form %}
            {{field}} 表示的就是控件
            {{field.label}}表示的是控件中label的值
          {% endfor %}
      2. 自动解析
        1. {{form.as_p}}
          将form对象中的每个属性使用p标记包裹起来,再显示
        2. {{form.as_ul}}
          将形成对象中的每个属性使用li标记包裹起来,再显示在网页上
          注意:必须手动提供<ol> </ ol>或<ul> </ ul>
        3. {{form.as_table}}
          将形成对象中的每个属性使用TR标记包裹起来,再显示在网页上,
          注意:必须手动提供的<table>
          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <style>
              /*#id_subject{
                border:2px solid #f00;
              }*/
          
              input[name='subject']{
                border:2px solid #ff0;
                border-radius:3px;
              }
            </style>
          </head>
          <body>
            <form action="/04-form/" method="post">
              {% csrf_token %}
              {% comment '手动解析' %}
              {% for field in form %}
                <p>
                  {{ field.label }}:{{ field }}
                </p>
              {% endfor %}
              {% endcomment %}
              <ul>
                {{ form.as_ul }}
              </ul>
              <p>
                <input type="submit" value="提交">
              </p>
            </form>
          </body>
          </html>
  4. 在视图中,通过forms.Form自动获取表单数据
    1. 通过forms.Form的构造器来接收post数据
      form = XXXForm(request.POST)
    2. 必须使形式通过验证之后,再取值
      form.is_valid()
      返回True:提交的数据已通过所有验证,允许取值(返回的是一个字典)
      返回False:提交的数据未通过验证,无法取值
    3. 表单电子杂志中数据
      通过form.cleaned_data来接收提交的数据

示例请点击

udfq

猜你喜欢

转载自blog.csdn.net/qq_42584444/article/details/83176077