昨日内容回顾
# 视图函数必须返回一个HttpResponse对象
HttpResponse
redirect
render
# json格式的数据
序列化:
import json
dumps
loads
反序列化
from django.http import JsonResponse
return JsonResponse('字典', json_dumps_params={'ensure_ascii':False}, safe=False)
form表单:
'''
1. 提交数据的方式必须是:post
2. enctype='form-data'
'''
后端如何处理:
request.GET
request.POST
request.FILES : 文件数据都在这个里面
# FBV: function based view
# CBV:
class based view
# 路由
'''
必须继承View
'''
from django.views import View
fbv: url('', views.index)
cbv:url('', views.类名.as_view())
# 一旦请求来了,会自动触发View.view()
# 1. 传值
1.1 {}
1.2 locals()
1.3 所有数据类型都允许传值
'''强调:一般能在python代码中实现的功能,都不要在页面中实现'''
# 2. 过滤器:
# 相当于内置方法
2.1 length
2.2 default
2.3 date
2.4 filesizeformat
2.5 safe
...
今日内容概要
- 模板语法之标签
- 模板语法继承
- 模板导入
- 测试环境的搭建
- ORM的查询方法
- 基于双下滑线的查询
- 外键字段的增删改查
内容详细
1. 模板语法之标签
# 在urls.py路由文件中添加:
url(r'^index/', views.index),
# 在views.py文件中写入:
def index(request):
dict = {'jason': 123, 'ly': 456}
# l = [1, 2, 3, 4, 5, 6]
return render(request, 'index.html', locals())
# 新建 index.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{#{% for foo in l %}#}
{# <p>#}
{# {{ forloop }}#}
{# {% if forloop.first %}#}
{# 第一次#}
{# {% elif forloop.last %}#}
{# 最后一次#}
{# {% else %}#}
{# {{ foo }}#}
{# {% endif %}#}
{# </p>#}
{#{% endfor %}#}
{% for foo in dict.keys %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in dict.values %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in dict.items %}
<p>{{ foo }}</p>
{% endfor %}
</body>
</html>
![image]()
![image]()
2. 模板继承
# 一个页面被其他页面公共使用
# 在urls.py路由文件中添加:
url(r'^reg/', views.reg),
url(r'^login/', views.login),
# 在views.py文件中添加:
def reg(request):
return render(request, 'reg.html')
def login(request):
return render(request, 'login.html')
# home.html文件内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% block css %}
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="/home/" class="list-group-item active">
男人的天堂
</a>
<a href="/reg/" class="list-group-item">注册</a>
<a href="/login/" class="list-group-item">登录</a>
<a href="#" class="list-group-item">开通会员</a>
<a href="#" class="list-group-item">视频聊天</a>
</div>
</div>
<div class="col-md-9">
<div class="jumbotron">
<h1>Hello, world!</h1>
{% block content %}
<p>性感荷官 在线发牌哦</p>
{% endblock %}
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
</div>
</div>
</div>
{% block js %}
{% endblock %}
</body>
</html>
# 新建注册页面文件 reg.html:
{% extends 'home.html' %} {# 将home.html文件内所有代码复制到当前文件 #}
{% block css %}
<style>
.c1 {
color: red;
}
</style>
{% endblock %}
{% block content %}
<h1>注册页面</h1>
<div class="c1">注册有惊喜哦</div>
{% endblock %}
{% block js %}
<script>
alert(123)
</script>
{% endblock %}
# 新建登录页面文件 login.html:
{% extends 'home.html' %} {# 将home.html文件内所有代码复制到当前文件 #}
{% block content %}
<h1>登录页面</h1>
{% endblock %}
# 补充:
引入非完整的left.html文件 以登录页面文件为例:
登录页面文件 login.html:
{% extends 'home.html' %} {# 将home.html文件内所有代码复制到当前文件 #}
{% block content %}
<h1>登录页面</h1>
{% include 'left.html' %}
{% endblock %}
left.html文件内容:
<h2>这是left</h2>
![image]()
![image]()
![image]()
3. 测试环境搭建
# 在tests.py文件中添加:
# 配置环境
import os
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "mysite5.settings")
import django
django.setup()
# 代码都要写在这个下面
from app01 import models
4. ORM查询方法
# 先django连接数据库
修改settings.py配置文件:
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': { # 添加该字典
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day06', # 库名
'HOST': '127.0.0.1',
'POST': 3306,
'USER': 'root',
'PASSWORD': '123',
'CHARSET': 'UTF8'
}
}
# 通过models.py文件中创建表:
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.IntegerField()
def __str__(self):
return self.title
# 在 tests.py操作数据库 写入:
"""
# 配置环境
import os
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "mysite5.settings")
import django
django.setup()
# 代码都要写在这个下面
from app01 import models
# 创建表记录
# models.Book.objects.create(title='小泽玛丽亚', price=100)
# models.Book.objects.create(title='泷泽萝拉', price=150)
# models.Book.objects.create(title='波多野结衣', price=500)
# 1.all first()
# res = models.Book.objects.all()
# res1 = models.Book.objects.all().first()
# res2 = models.Book.objects.all().last()
# print(res) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>, <Book: 波多野结衣>]>
# print(res1) # 小泽玛丽亚
# print(res2) # 波多野结衣
# 2.get
# res = models.Book.objects.filter()
# res1 = models.Book.objects.filter(pk=1)
# res2 = models.Book.objects.filter(pk=1).first()
# # res3 = models.Book.objects.get(pk=5) # 查询的数据必须存在,不存在直接报错
# print(res) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>, <Book: 波多野结衣>]>
# print(res1) # <QuerySet [<Book: 小泽玛丽亚>]>
# print(res2) # 小泽玛丽亚
# # print(res3)
'''一般不推荐使用get方法'''
# 3.exclude
# res = models.Book.objects.exclude(pk=1) # 查询pk=1之外的数据,其实就是排除数据
# print(res) # <QuerySet [<Book: 泷泽萝拉>, <Book: 波多野结衣>]>
# 4. order by
# SQL语句写法:select *from t1 order by id asc, price desc, title asc
# res = models.Book.objects.order_by('id') # 默认是升序
# res1 = models.Book.objects.order_by('-id', 'price') # 默认是降序 多字段排序:只有前一个字段一样时 才会按下一个字段排序
# print(res) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>, <Book: 波多野结衣>]>
# print(res1) # <QuerySet [<Book: 波多野结衣>, <Book: 泷泽萝拉>, <Book: 小泽玛丽亚>]>
# 5.反转
# res = models.Book.objects.order_by('id').reverse() # 默认是降序
# print(res) # <QuerySet [<Book: 波多野结衣>, <Book: 泷泽萝拉>, <Book: 小泽玛丽亚>]>
# 6.count 查询某个字段出现几个
# SQL语句写法: select count(1) from t1
# res = models.Book.objects.count() # 查询有几个字段
# res1 = models.Book.objects.filter(price=100).count() # 查询price为100的字段有几个
# print(res) # 3
# print(res1) # 1
# 7.exists 查询是否存在
# res = models.Book.objects.filter(pk=1).exists()
# print(res) # True
# 8.values 按指定字段查询
# SQL语句写法:select title, price from t1
# res = models.Book.objects.values('title', 'price') # 列表套字典
# res1 = models.Book.objects.values_list('title', 'price') # 列表套元组
# print(res) # <QuerySet [{'title': '小泽玛丽亚', 'price': 100}, {'title': '泷泽萝拉', 'price': 150}, {'title': '波多野结衣', 'price': 500}]>
# print(res1) # <QuerySet [('小泽玛丽亚', 100), ('泷泽萝拉', 150), ('波多野结衣', 500)]>
# 9.去重:一定不加主键(因为主键不会重复)
# SQL语句写法: select distinct name from t1
res = models.Book.objects.values('title', 'price').distinct()
print(res) # <QuerySet [{'title': '小泽玛丽亚', 'price': 100}, {'title': '泷泽萝拉', 'price': 150}, {'title': '波多野结衣', 'price': 500}]>
"""
![image]()
5. 基于双下滑线的查询
# 在 tests.py操作数据库 写入:
# 配置环境
import os
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', "mysite5.settings")
import django
django.setup()
# 代码都要写在这个下面
from app01 import models
# 基于双下滑线的查询
# 1. 查询书籍价格大于200的
# SQL语句写法:select * from t1 where price > 200
# ORM语句:gt => greater than equal
# res = models.Book.objects.filter(price__gt=200).all()
# res1 = models.Book.objects.filter(price__gte=200).all()
# print(res) # QuerySet [<Book: 波多野结衣>]>
# print(res1) # QuerySet [<Book: 波多野结衣>]>
# 2. 查询书籍价格小于200的
# res = models.Book.objects.filter(price__lt=200).all()
# res1 = models.Book.objects.filter(price__lte=200).all()
# print(res) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>]>
# print(res1) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>]>
# 3. 查询书籍价格是111 或 300的所有书籍
# sql:select * from t1 where price = 111 or price = 200
# sql:select * from t1 where price in (111, 200)
# in走索引,not in 不走索引
# res = models.Book.objects.filter(price__in=[111, 300]).all()
# print(res) # <QuerySet []>
# 4. 查询书籍价格在100-300之间的
# sql:select * from t1 where price >= 100 and price <= 300
# sql: select *from t1 where price between 100 and 300
# 顾头顾尾
# res = models.Book.objects.filter(price__range=[100, 300]).all()
# print(res) # <QuerySet [<Book: 小泽玛丽亚>, <Book: 泷泽萝拉>]>
# 5. 查询书籍名称带有 衣 的所有书籍
# like查询不走索引
# es: elasticsearch
# sql:select * from t1 where title like '衣%'
# res = models.Book.objects.filter(title__contains='衣').all()
# # 返回结果一定是queryset对象,才能点query属性
# print(res.query) # 查看表字段
# print(res) # <QuerySet [<Book: 波多野结衣>]>
"""
select book.id, book.title from t1
create table db1.t (id int, name varchar(16))
"""
# 6. 查询以 波 开头的数据 以 亚 结尾的数据
# res = models.Book.objects.filter(title__startswith='波').all()
# res1 = models.Book.objects.filter(title__endswith='亚').all()
# print(res) # <QuerySet [<Book: 波多野结衣>]>
# print(res1) # <QuerySet [<Book: 小泽玛丽亚>]>
# 7. 以时间查询: 2021-10
# res = models.Book.objects.filter(create_time__year=2021, create_time__month=10)
6. 查看SQL执行语句
# 1.如果当前对象是queryset那么可以直接点query查找该对象内部SQL语句
# 2.在settings.py 配置文件(只要执行orm语句都会自动打印SQL语句)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
![image]()