• django基础2


    一. 使用原生sql,了解即可
    使用原生sql的目的:解决一些复杂的sql不能用ORM方式写出的问题
    有三种方式如下
    1. extra: 结果集修改器,一种提供额外查询参数的机制
    2. raw:执行原始sql并返回模型实例
    3. 直接执行自定义的SQL
    前两种方式要依赖于model,第三种不依赖model
     
    实例
    使用extra来扩展查询条件
    1. Book.objects.filter(publisher__name='广东人民出版社').extra(where=['price>50'])
    也可以写成
    Book.objects.filter(publisher__name='广东人民出版社',price__gt=50)
     
    2. Book.objects.extra(select={'count':'select count(*) from hello_book'})
    这里把select count(*) from hello_book做为一个整体,别名为count
     
     
    使用raw方法来执行原始sql语句,最好用于查询
    1. Book.objects.raw('select * from hello_book')
    作用就是执行select * from hello_book,返回类型是RawQuerySet,可进行遍历
     
    2. bbb=Book.objects.raw("insert into hello_author(name) value('lilei')")
     
     
    直接执行自定义sql,这种方法最灵活
    from django.db import connection
    cursor = connection.cursor() #获得一个游标对象
    插入操作
    cursor.execute("insert into hello_author(name) value('阿里')")
    更新
    cursor.execute("update hello_author set name='韩寒' where name='郭敬明'")
    删除
    cursor.execute("delete from hello_author where name='韩寒'")
    查询
    cursor.execute('select * from hello_author')
    raw=cursor.fetchone()   #取出查询的结果,每次一个作者信息
    cursor.fetchall()  #取出所有的作者信息,以元组类型返回
    需要注意的是当取到最后一条作者信息后,再用fetchall()取出的是空值,需要重新执行一下查询语句。
     
     
     
    二. 常用模板标签及过滤器
     
    1. 模板的组成:HTML代码+逻辑控制代码
    2. 逻辑控制代码的组成
    1)变量,使用大括号来引用变量,一般从views.py中传过来
    {{ var_name }}
     
    2)标签的使用
    {% load staticfiles %}
     
    3)过滤器(filter)的使用
    {{ ship_date|date:"Fj,Y" }}  ship_date变量传给date过滤器,date过滤器通过使用"Fj,Y"这几个参数来格式化日期数据。 “|”就是过滤符
     
    3. 常用标签
    {% with %} :在标签作用域中,用简单的变量名替代复杂变量名
    {% url %}:引入路由配置的地址,如下
    在urls.py中url(r' ^test/$', views.test, name='test')
    在html文件中<form method='post' action="{% url 'test' %},其中的test为urls.py中的路由别名。模板中的url一般不写死
    {% cycle %}:在循环时轮流使用给定的字符串列表中的值
    {% load %}:加载标签库
    {% csrf_token %}:生成csrf_token标签,用于防止跨站攻击验证,post表单中常用
    {% autoescape %}:自动转义设置
    {% now %}:获取当前时间
    {% if %}:可以使用and, or, not 来组织逻辑,但不允许and,or同时出现在条件语句中,新版本中支持{% elif %}
    {% for %}:用来循环一个list,还可以用reversed关键字进行倒序遍历,一般可以用if语句来判断一下列表是否为空,再进行遍历;还可以用empty关键字来进行为空时的跳转
    <ul>
    {% for athlete in athlete_list %}
        <li>{{athlete}}</li>
    {% empty %}
        <li>sorry, no athlete </li>
    {% endfor %}
    </ul>
     
     
    标签和过滤器完整介绍
     
     
    4. 过滤器
    我们一般都是通过变量来使用过滤器
    {{ value1|uppper }}  把变量value1的字母大写
     
    常用过滤器有
    1. add:给变量加上相应值,进行加法运算{{ value2|add: "2" }}
    2. addslashes:给变量中的引号前加上斜线
    3. capfirst:首字母大写
    4. cut:从字符串中删除指定的字符
    5. date:格式化日期字符串
    6. default: 如果值为False,就替换成设置的默认值,否则使用本来值
    代表False的情况有空字符串,空列表,空字典,False字符串
    7. default_if_none: 如果值为None,就替换成设置的默认值,否则使用本来值
    8. escape:对字符串进行转义
    9. filesizeformat: 格式化文件大小显示
    10. first,last:返回列表的第一个,最后一个元素
    11. length:返回列表长度
    12. slice:切片操作,{{ some_list | slice:":2" }}
    13. truncatechars: 按照字符截取字符串,后跟数字表示截取的长度
    14. truncatewords:按照单词截取字符串,其实是按空格截取
    15. striptags:过滤掉html标签,常用于安全处理
     
     
     
    5. 模板的包含和继承
    解决网页公用部分的冗余问题
     
    1)包含
    {% include %} 允许在模板中包含其他模板的内容
     
    标签的参数可以是:模板名称,变量,字符串
    {% include 'nav.html' %}   #模板名称
    {% include 'app/nav.html' %}  #模板路径
    {% include template_name %}  #模板的变量,比较少用
    比如在views.py中
    from django.template import Template
    def hello(request):
        value9=Template("<a href='http://www.baidu.com' target='_blank'>百度</a>")
     
    那么在html文件中就可以用变量来代替模板
    {% include value9 %}
     
    注意:
    锚链接可以选用target属性控制点击链接时的行为,_blank是该属性可用值之一,点击链接时会告知浏览器打开一个新的窗口
     
    可以在包含的时候传递变量,使用关键字with
    比如在table.html中有如下代码
    {% include 'app/nav.html' with hello='hello, Django' %}
    然后在nav.html中写入如下代码即可
    <p> {{ hello }} </p>
     
    include标签官方说明
     
     
    2)继承
    模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点共用部分进行重载,主要用到2个相关标签 {% block %}, {% extends %}
     
    定义块 ,就是共用部分
    继承父模板
     
    注意
    1. 通常尽可能在父模板中用{% block %}来预留位置,子模板不必定义所有的父block,其实就是子块覆盖父块
    2. 如果需要得到父模板的块内容,可用{{ block.super }}变量,当你需要给父块添加内容而不是取代它时,这个很有用
    比如在父模板base.html中
    <title>
    {% block title %} my amazing site {% endblock %}
    </title>
    在子模板a.html中
    {% extends "base.html" %}
    {% block title %} {{ block.super }} - 我的第一个子网页{% endblock %}
     
    这样子模板的标题输出为my amazing site - 我的第一个子网页
     
     
     
    三. admin基本配置
     
    django amdin是django自带的后台管理工具
     
    1. ModelAdmin是管理界面的定制类,如需扩展特定的model界面需要从该类继承
     
     
    2. 注册model类到admin的两种方法
    1)使用register的方法
    2)使用register的装饰器
     
    3. 掌握一些常用的设置技巧
    list_display:指定要显示的字段
    search_fields:指定搜索的字段,后台会多一个搜索框
    list_filter:指定列表过滤器, 后台页面右上边会多一部分FILTER内容
    ordering:指定排序字段
    fieldsexclude:指定编辑表单需要编辑不需要编辑的字段
    fieldsets:设置分组表单
     
    admin官方文档
     
     
    例子:后台只会显示出版社的名字,如果想要显示出版社的其他信息,应该怎么做呢? 
    自定义一个类
    from django.contrib import admin
    from hello.models import *
     
    @admin.register(Publisher)  #使用装饰器来注册,效果和下面的register效果一样
    class PublisherAdmin(admin.ModelAdmin):
        list_display = ('name', 'address', 'city',)
        search_fields = ('name', 'city',) #元组只有一个元素时,后面必须加逗号
        list_filter = ('city',) #和search_fields效果相似,表现形式不同
        orderding = ('-id',)
        #fields = ('name', 'address',) #就是新增出版社时,能够编辑的属性
     
        fieldsets = (
            (None, {
                'fields': ('name', 'address', )
            }),
            ('Advanced options', {
                'classes': ('collapse',),
                'fields': ('city', 'website'),
            }),
        )
        效果就是页面显示name, address可编辑,而city, website是属于高级选项,默认是隐藏的,需要自己点击show按钮才会展开显示
     
    #admin.site.register(Publisher, PublisherAdmin)   #使用register来注册model的方法
     
     
     
    四. Django中的表单系统
     
     
    django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm
     
    表单系统主要分两种
    1. 基于django.forms.Form: 所有表单类的父类
    2. 基于django.forms.ModelForm: 可以和模型类绑定的Form
     
     
    案例:实现添加出版社信息的功能
     
    方法1. 用原生表单写
    views.py中写
    def add_publisher(request):
        if request.method == 'POST':
            name = request.POST['name'] 
            address = request.POST.get('address') #这种方法和上面的等效
            city= request.POST['city']  #中括号中的city为html文件中的name属性值
     
            #使用create的方法写入数据库,其中等号右边是上面的变量,左边是数据库列名
            Publisher.objects.create(
                name = name,
                address = address,
                city = city,
            )
            return HttpResponse("添加出版社信息成功")
     
        else:
            return render(request, 'add_publisher.html', locals())
     
     
    urls.py中
    urlpattern = [
        url(r' ^add_publisher/$', views.test, name='add_publisher'),
    ]
     
     
    定义个模板add_publisher.html
    <head>
         <title>添加出版社信息</title>
    </head>
    <body>
    <form action="{% url 'add_publisher' %}" method="post">  其中add_publisher为url.py中的别名,使用了url标签
        {% csrf_token %} 不加这个会报403错误
        名称:<input type="text" name="name"><br>
        地址:<input type="text" name="address"><br>
        城市:<input type="text" name="city"><br>
        <input type="submit" value="提交"><br>
    </form>
     
     
     
    方法2,使用django.forms.Form
     
    1. 首先在app里新增一个forms.py文件
    from django import forms
     
    class PublisherForm(forms.Form)
        name =  forms.CharField(label="名称",error_message=("required":"这个项目必填") 用label定义属性后台显示信息,不加就显示为name
        address =  forms.CharField()
        city =  forms.CharField()
     
     
    2. views.py中导入定义的forms文件
    from hello.forms import PublisherForm
     
    def add_publisher(request):
        if request.method == 'POST':
            publisher_form = PublisherForm(request, POST) #表单对象初始化,使对象里含有POST传入的值
            if publisher_form.is_valid():  #验证表单数据是否合法,比如空数据
                Publisher.objects.create(
                     name = publisher_form.cleaned_data['name'],
                     address = publisher_form.cleaned_data['address'],
                     city = publisher_form.cleaned_data['city'],     
                )
                return HttpResponse("添加出版社信息成功")
     
       else:
            publisher_form = PublisherForm()  初始化一个表单对象,使模板能接收这个对象
     
       return render(request, 'add_publisher.html', locals())  #验证没通过也需要渲染出来
          
        
     
    3. add_publisher.html文件可改写为如下
    <head>
         <title>添加出版社信息</title>
    </head>
    <body>
    <form action="{% url 'add_publisher' %}" method="post"> 
        {% csrf_token %} 
       {{ publisher_form.as_p }} #可自动生成表单信息,as_p是每个表项标签为<p>
        <input type="submit" value="提交"><br>
    </form>
     
     
     
    方法3,使用django.forms.ModelForm
    1. forms.py
    from django import forms
    from hello.models import Publisher
     
    class PublisherForm(forms.ModelForm)
        
        class Meta:
            model = Publisher #绑定Publisher类
            exclude = ("id",)  #排除id字段,其他都显示
             
     
     
    2. views.py
    from hello.forms import PublisherForm
     
    def add_publisher(request):
        if request.method == 'POST':
            publisher_form = PublisherForm(request, POST) 
            if publisher_form.is_valid():  
                publisher_form.save()  #插入数据用一条代码就搞定
                return HttpResponse("添加出版社信息成功")
     
        else:
            publisher_form = PublisherForm()
     
        return render(request, 'add_publisher.html', locals())
     
     
    资料
     
     
     
     
     
    五 .表单验证
     
    Django提供了三种方式来验证表单
     
    1. 表单字段的验证器
     
    2. clean_filedname(filedname为字段名称),验证字段,针对某个字段进行验证
     
    3. 表单clean方法,可针对整个表单进行验证
     
    案例
    自定义验证,不能插入重名的出版社名称
     
    方法一. 表单字段验证器
     
    forms.py文件中
     
    from django import forms
    from hello.models import Publisher
    from django.core.exceptions import ValidationError
     
    def validate_name(value):  #这里的参数value相当于一个回调函数,放在哪个字段就给哪个字段值
        try:
            Publisher.objects.get(name=value)
            raise ValidationError("%s的信息已经存在"%value)
        except Publisher.DoesNotExist:
            pass
     
    class PublisherForm(forms.ModelForm)
        
        #添加一个字段,如果和绑定的Publisher模块中的字段重名的话,就不会重复添加
        name = forms.Charfield(lable="名称", validators=[validate_name])
        
        class Meta:
            model = Publisher #绑定Publisher类
            exclude = ("id",)  #排除id字段,其他都显示
     
     
    方法二. 针对某个字段进行验证
    forms.py文件中
     
    from django import forms
    from hello.models import Publisher
    from django.core.exceptions import ValidationError
     
    class PublisherForm(forms.ModelForm)
        
        def clean_name(self):
            value =  self.cleaned_data.get('name') #定义个value值供下面的try语句中的value参数用
     
            try:
                Publisher.objects.get(name=value)
                raise ValidationError("%s的信息已经存在"%value)
            except Publisher.DoesNotExist:
                pass
            return value  #在没有出错的情况下要返回value值,这是这种方法的特殊性
        
        class Meta:
            model = Publisher #绑定Publisher类
            exclude = ("id",)  #排除id字段,其他都显示
     
     
    方法三. 表单clean方法,对整个表单进行验证
    forms.py文件中
     
    from django import forms
    from hello.models import Publisher
    from django.core.exceptions import ValidationError
     
    class PublisherForm(forms.ModelForm)
        
        def clean(self):
            cleaned_data = super(PublisherForm, self).clean() #继承父类clean()
            value = cleaned_data.get('name') #定义个value值供下面的try语句中的value参数用
     
            try:
                Publisher.objects.get(name=value)
                self._errors['name']=self.error_class(["%s的信息已经存在"%value])
                
            except Publisher.DoesNotExist:
                pass
            return cleaned_data  #这里返回整个表
        
        class Meta:
            model = Publisher #绑定Publisher类
            exclude = ("id",)  #排除id字段,其他都显示
  • 相关阅读:
    原创 爱因斯坦迷题及推导过程
    惊闻姑姑家女婿去世,哀叹生命之脆弱,死亡如此接近
    京东自营预售逻辑
    自营SKU绑定逻辑
    自营结算解释&对账逻辑
    CPS逻辑
    京东搜索结果数据异常
    C++静态库中使用_declspec(dllexport) 不能导出函数的问题
    HTTP+SVN访问速度慢的问题
    Python log
  • 原文地址:https://www.cnblogs.com/regit/p/9243477.html
Copyright © 2020-2023  润新知