Python学习之路—2018/6/25
1.模板语法之标签
csrf_token
当form表单提交时,会出现以下错误
解决方案:
1.找到settings.py→MIDDLEWARE→django.middleware.csrf.CsrfViewMiddleware并注释掉
2.利用csrf_token标签
login.html
<form action="" method="post">
{% csrf_token %}
用户名<input type="text" name="usr">
密码<input type="password" name="usr">
<input type="submit">
</form>
实质上是添加了一个隐藏的input标签,标签中含有身份信息,render解析后将通过请求的信息传递给浏览器
2.自定义标签和过滤器
1.在settings中的INSTALLED_APPS中配置app01
2.在app01目录下创建一个templatetags模块(注:名字必须是这个)
3.创建文件
自定义过滤器
my_tags.py
from django import template
register = template.Library() # register名字不可更改
@register.filter
def multiple_filter(x, y): # 最多只能接受两个参数
return x+y
index.html
<h1>自定义过滤器</h1>
<p>
{% load my_tags %} {# 首先需要将自定义的过滤器或者标签导入 #}
{{ i|plus_filter:100 }} {# 100+100 #}
</p>
自定义标签
my_tags.py
@register.simple_tag
def plus_tag(x, y, z): # 可以接受多个参数
return x+y+z
index.html
<h1>自定义标签</h1>
<p>
{% load my_tags %}
{% plus_tag 1 2 3 %} {# 1+2+3 #}
</p>
自定义过滤器与标签的不同
- 自定义过滤器最多接受两个参数,而自定义标签可以接受多个参数
- 在html文件中,自定义过滤器通过{{ xxx|过滤器名:参数 }}调用,自定义标签通过{% 标签名 参数1 参数2 参数3... %}调用
- 自定义过滤器的参数可用于if等语句后面,自定义标签不行
index.html
<p>
{% if i|plus_filter:100 > 120 %}
{{ i|plus_filter:100 }}
{% else %}
{{ 120 }}
{% endif %}
</p>
3.模块语法之继承
{% include %}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-3">
{% include 'advertise.html' %} {# 此处引用advertise.html #}
</div>
<div class="col-md-9">
{% load my_tags %}
<p>
{% if i|plus_filter:100 > 120 %}
{{ i|plus_filter:100 }}
{% else %}
{{ 120 }}
{% endif %}
</p>
<h1>自定义标签</h1>
<p>
{% plus_tag 1 2 3 %}
</p>
<h1>自定义过滤器</h1>
<p>
{{ i|plus_filter:100 }}
</p>
<p>{{ a }}</p>
<p>{{ content|truncatechars:10 }}</p>
<p>{{ s|slice:"0:3" }}</p>
<p>{{ date|date:"Y-m-d" }}</p>
<p>{{ value|filesizeformat }}</p>
<p>{{ l|default:"nothing" }}</p>
<p>{{ dic|length }}</p>
</div>
</div>
</div>
</body>
</html>
advertise.html
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">1</h3>
</div>
<div class="panel-body">
qwer
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">2</h3>
</div>
<div class="panel-body">
asdf
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">3</h3>
</div>
<div class="panel-body">
zxcv
</div>
</div>
展示效果:
{% extends %}
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}
Base
{% endblock title %}
</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="col-md-3">
{% include 'advertise.html' %}
</div>
<div class="col-md-9">
{% block content %}
<h1>content</h1>
{% endblock content %}
</div>
</div>
</body>
</html>
win.html
{% extends "base.html" %}
{% block title %}
win
{% endblock title %}
{% block content %}
<h1>展示内容</h1>
{% endblock content %}
展示效果:
注意:
-
{% extends %}使用时必须放在第一行
-
父模块中的block盒子,子模块如果没有定义内容则最终显示父模块中的内容,如果定义了则会覆盖父模块的内容
-
如果想要不覆盖父模块的内容,需要用{{ block.super }}
win.html
{% extends "base.html" %}
{% block title %}
win
{% endblock title %}
{% block content %}
{{ block.super }}
<h1>展示内容</h1>
{% endblock content %}
展示效果:
- 可以对block定义名字加以区分,但是同一模块中block标签的名字不能相同
4.ORM简介
单表操作
创建模型
app01.models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publish_date = models.DateField()
price = models.DecimalField(max_digits=8, decimal_places=2)
配置
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'orm',
'USER': 'root',
'PASSWORD': 'admin',
'HOST': 'localhost',
'PORT': 3306
}
}
如果想打印orm转换过程中的sql,需要在settings中进行如下配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
orm.__init__.py
import pymysql
pymysql.install_as_MySQLdb()
命令
python manage.py makemigrations
python manage.py migrate
添加记录
urls.py
urlpatterns = [
path('add/', views.add),
]
view.py
from django.shortcuts import render,HttpResponse
from .models import Book
def add(request):
book_obj = Book.objects.create(title="python", publish_date="2014-06-06", price=125)
print(book_obj)
return HttpResponse("OK")
运行结果:
查询API
数据:
all()
查询所有结果
>>> book_list = Book.objects.all()
<QuerySet [<Book: python>, <Book: linux>, <Book: java>, <Book: go>]>
first(),last()
查询结果的第一个和最后一个
>>> book_first = Book.objects.all().first()
python
>>> book_first = Book.objects.all().last()
go
filter()
返回筛选后的所有结果,多个条件时用逗号隔开
>>> book_filter_list = Book.objects.filter(price=125)
<QuerySet [<Book: python>]>
get()
当筛选的而结果是唯一的时候返回对象,结果不唯一会报错
>>> book_filter = Book.objects.get(price=115)
linux
>>> book_filter = Book.objects.get(price=100)
exclude()
排除符合条件的数据
>>> book_exfilter_list = Book.objects.exclude(price=115)
<QuerySet [<Book: python>, <Book: java>, <Book: go>]>
order_by()
按照字段进行排序,默认按照id升序排序,字段前面加上符号则降序
>>> book_list_order = Book.objects.all().order_by("price")
<QuerySet [<Book: java>, <Book: go>, <Book: linux>, <Book: python>]>
>>> book_list_order1 = Book.objects.all().order_by("-price")
<QuerySet [<Book: python>, <Book: linux>, <Book: java>, <Book: go>]>
reverse()
反向排序
count()
返回筛选结果的数目
>>> ret = Book.objects.filter(price=100).count()
2
exists()
如果筛选结果存在则返回True,否则返回False
>>> result = Book.objects.filter(price=200).exists()
False
values()
将每个筛选后的结果放入字典中,返回querylist对象
>>> ret_values = Book.objects.all().values("price", "title")
<QuerySet [{'price': Decimal('125.00'), 'title': 'python'}, {'price': Decimal('115.00'), 'title': 'linux'}, {'price': Decimal('100.00'), 'title': 'java'}, {'price': Decimal('100.00'), 'title': 'go'}]>
values_list()
将每个筛选后的结果放入元祖中,返回querylist对象
>>> ret_values_list = Book.objects.all().values_list()
<QuerySet [(1, 'python', datetime.date(2014, 6, 6), Decimal('125.00')), (2, 'linux', datetime.date(2014, 12, 6), Decimal('115.00')), (3, 'java', datetime.date(2018, 1, 17), Decimal('100.00')), (4, 'go', datetime.date(2017, 5, 25), Decimal('100.00'))]>
distinct()
去除重复记录