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字段,其他都显示
原文地址:https://www.cnblogs.com/regit/p/9243477.html