第二篇主要讲了修改数据库的操作和模型层的一些知识,戳链接==>https://blog.jixiaob.cn/?post=39
————————————————————————————————————————
用户查询验证
def get_user(request): username = 'Sunck' password = '1d20' users = User.objects.filter(u_name=username) if users.count(): # 这里也可以用users.exists()判断是否存在 user = users.first() # 这里的u_name字段设定为了不可重复,所以first和last都行 if user.u_password == password: print("获取用户信息成功") else: print('密码错误') else: print("用户不存在") return HttpResponse("获取成功")
————————————————————————————————————————
限制查询集和查询集的缓存(切片)
这个切片和Python的切片不太一样,下标不能是负数
QuerySet[5:15]获取第五条到第十五条数据,相当于SQL中的limit和offset
def get_users(request): users = User.objects.all()[1:3] # 切片获取第二条和第三条数据 context = { 'users': users, } return render(request, 'userlist.html', context=context)此时你打开对应的网址getusers之后,可能还会打开成getuser的网址。
(其实是我忘了加\了)
这是url 和path在Django2.2版本进行的更改导致的,出现上述情况肯定写的是url,改为path即可。记得from django.urls import path。
查询集缓存:每个查询集都包含一个缓存,来最小化调用数据库。不论filter、exclude、all了多少次,都不会真正的去访问数据库。只有在迭代结果集,或者获取单个对象属性的时候,它才会去查询数据库。这种查询叫做懒查询,是为了优化查询和结构。
——————————————————————————————————————————————
字段查询
属性__运算符=值
gt 大于 lt 小于 gte 大于等于 lte 小于等于 in 在某一个集合之中
contains 包含(类似于模糊查询的like) startswith 以XX开始 endswith 以XX结束 exact精确等于,相当于直接等于 这四个前面可以添加一个i,表示忽略大小写。
isnull isnotnull是否为空
时间运算符
year month day week_day hour minute second
filter(lastname__year=2021)
查询快捷:pk,代表主键 filter(pk=1)
Django 中的查询条件有时区问题。可以关闭Django中自定义的时区(settings里面USE_TZ = False)或者在数据库中创建对应的时区表(比较麻烦)
跨关系查询
比如查询哪一个班级里有叫Jack的
首先建立模型
class Grade(models.Model): g_name = models.CharField(max_length=16) class Student(models.Model): s_name = models.CharField(max_length=16) s_grade = models.ForeignKey(Grade, on_delete = models.CASCADE)
当然也可以先查学生中的Jack,再查对应的班级。不过这样比较麻烦。
Django中提供了一种直接查询的方式
def get_grades(request): grades = Grade.objects.filter(student2__s_name='Jack') for grade in grades: print(grade.g_name) return HttpResponse('获取成功')
聚合函数
Avg平均值 Count数量 Max最大 Min最小 Sum求和
from django.db.models import Max
Student.objects.aggregate(Max('s_age'))
会返回一个字典
F对象
F对象可以简单的获取到一个模型的属性的值
可以实现一个模型的不同属性的运算操作
比如获取女生人数比男生多的公司
conpanies = Company.object.filter(c_boy_num__lt=F('c_girl_num') - 15 ) # 这里使用了F对象来获取女生人数,后面可以运算
Q对象
常用于组合条件。可以对条件进行封装,封装之后可以支持逻辑运算与(& and)、或(| or)、非(~ not)
可以把链式调用改成Q对象
比如上一篇写的:
persons = Person.objects.filter(p_age__gt=50).filter(p_age__lt=80) # 获取年龄50<年龄<80的人
可以改为:
persons = Person.objects.filter(Q(p_age__gt=50) & Q(p_age___lt=80))这样可以把多个条件写到一个filter中
模型成员
显性属性:开发者手动书写的属性 隐性属性:开发者没有书写,ORM自动生成的,如objects是一个models.Manager()
如果把隐形属性写成了显性属性,隐形属性就不会自动生成了
比如在其中一个类中声明一个abc_manager = models.Manager() 这样之前的objects就不能用了
另外自定义这个模型管理可以先继承然后自定义属性
在父类中定义一个自己的manager类,继承models.Manager()
在里面定义get_queryset(self)
class Self_manager(models.Manager): def get_queryset(self): return super(Self_manager, self).get_queryset().filter(is_delete=False) # 直接在这里面筛选掉删除的 然后上面的abc_manager要改为 abc_manager = Self_manager() # 当然如果之前都写了objects,这里也可以重新定义一下objects来统一解决
当然也可以在自己写的manager类中写一个造对象的方法:
def create_animal(self, a_name='Chicken'): a = self.model() a.a_name = a_name return a
——————————————————————————————————————————————
Templates模板
在Django中,模板是可以帮助开发者快速生成呈现给用户页面的工具。Django有独有的模板引擎。
模板的处理有加载和渲染两个过程。
# 常规渲染 from django.template import loader temp = loader.get_template('index.html') content = temp.render() return HttpResponse(content) # 简便写法 from django.shortcuts import render return render(request, 'index.html')
模板主要由两部分组成——静态的HTML和动态插入的代码段(挖坑、填坑)
模板中的动态代码段除了做基本的静态填充,还可以实现一些基本运算,转换和逻辑
模板中的变量:视图(view)传递给模板数据,遵守标识符规则,语法{{var}}
如果变量不存在,则插入空字符串
模板中的点语法
grades grade
字典查询 属性或方法 索引
<ul> {% for student in students %} <li>{{ student.s_name }} </li> # 这里的点是student的属性 {% endfor %} </ul>
如果在Student类里面写一个获取名字的函数
def get_name(self): return self.s_name在HTML模板里面这样用:
<ul> {% for student in students %} <li> {{ student.get_name }} </li> # 这里就是函数的用法 {% endfor %} </ul>
student.0.s_name 返回的是第一个学生的姓名,0就是充当索引的作用。1,第二个,2,第三个……
还可以传入字典,字典.key 可以得到value
模板的小弊端:调用对象方法时不方便传递参数。通常只调用不传参的函数。
标签
模板中的小标签:语法{% tag %} 作用:1.加载外部传入的变量 2.在输出中创建文本 3.控制循环或逻辑
标签分为单标签和成对的标签。成对的标签切记不能省略。
If结构:
# if结构 {% if 表达式 %} 语句 {% endif %} {% if 表达式 %} 语句 {% else %} 语句 {% endif %} {% if 表达式 %} 语句 {% elif 表达式 %} 语句 {% endif %}
for结构
{% for 变量 in 列表 %} 语句1 {% empty %} 语句2 {% endfor %}当列表为空或不存在时,执行empty之后的语句
forloop是一个循环状态的记录
{{ forloop.counter }} 表示当前是第几次循环,从1开始计数
forloop.counter0 表示当前是第几次循环,从0开始计数
forloop.recounter 表示第几次循环,倒着计数,1结束
forloop.recounter0 表示第几次循环,倒着计数,0结束
forloop.first 布尔值,是否为第一个
forloop.last 布尔值,是否为最后一个
下面代码把第一个的颜色变为了红色。如果空输出Sunck辍学了
<ul> {% for student in students %} {% if forloop.first %} <li style="color: red">{{ forloop.counter }}:{{ student.s_name }} </li> {% else %} <li>{{ forloop.counter }}:{{ student.s_name }} </li> {% endif %} {% empty %} <h1>Sunck辍学了</h1> {% endfor %} </ul>模板中的注释。这样写不会渲染到页面上
单行注释:{# 注释的内容 #}
多行注释:{% comment %}
内容
{% endcomment %}
乘除
{% widthratio 数 分母 分子 %} 只有乘的操作,写除转化成分数
{% if num|divisibleby:2 %} 如果整除
{% ifequal 值1 值2 %} 如果相等 {% endifequal %} 还有如果不相等{% ifnotequal %}
{% url 'namespace:name' p1 p2 %} URL反向解析
csrf_token 用于跨站请求伪造保护 {% csrf_token %}
过滤器
作用:在显示前修改
加减:add {{ p.page|add:5 }} 减就是加负数
转换大小写:lower upper {{ p.pname|lower }}
过滤器还可以传递参数,参数需要用引号引起来{{ students|join '=' }} 默认值{{ var|default value}} 变量没有值或为False 空会使用默认值 日期转字符串{{ dataVal|date:'y-m-d'}}
HTML转义
将接收到的数据当成普通字符串处理还是当HTML代码渲染的问题
{{ code|safe }} 把code的内容(HTML代码)渲染出来,而不是作为普通文本输出(谨慎使用!可能会出现js注入)
<script type="text/javascript">
alert("你的网站被攻陷了")
var lis = document.getElementsByTagName("li");
for (var i=0; i<lis.length; i++){
var li = lis[i];
li.innerHTML="喵喵";
}
</script>
{{% autoescape off %}} 这里吧off改为on就不会渲染出来了
code
{{% endautoescape %}}
模板继承
关键字block:挖坑
# base.html <head> <meta charset="UTF-8"> <title>{{ title }}</title> </head> <body> {% block header %} {% endblock %} {% block banner %} {% endblock %} {% block content %} {% endblock %} </body>
# home.html 填坑
{% extends 'base.html' %} {% block header %} <h3>哈哈哈,这是一个头</h3> {% endblock %}
结构标签:
block:块,用来规划布局。首次出现代表规划,第二次出现代表填充以前的规划。
block.super可以继承而不是覆盖,实现增量式操作
{% extends 'home.html' %} {% block content %} <h3>哈哈哈</h3> {% endblock %} {% block header %} {{ block.super }} <h4>听说你很精神</h4> {% endblock %}
extends:继承模板,可以获取父模板的所有结构。
block + extends :化整为零
include 包含,可以将页面作为一个模块(一部分),嵌入到其它页面中
{%block footer %}
{% include 'footer.html' %}
{% endblock %}
include + block 由零聚一
三个标签可以混合使用。但是能用第一个搞定的就尽量不要使用include(include效率较低)
在子模板中无法重写父模板里面的内容。
js,css,image等静态文件通常放在static文件夹。
在base.html中外挂css
{% block ext_css %} {% endblock %}在home_mine中
{% block ext_css %} <link rel="stylesheet" href="/static/css/home_mine.css"> {% endblock %}在home_mine.css中:
h3{ color: red; }然后在settings里面注册一下静态文件路径(别忘了在项目跟目录创建static文件夹):
STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ]
上面的写法一般不推荐,也可以这样写,写成标签式写法的相对路径:
home_mine.html里面:
{% load static %} # 开头这两个任选一个 {% load staticfiles %}
{% block ext_css %} <link rel="stylesheet" href="{% static 'css/home_mine.css' %}"> {% endblock %}但是debug改为False就不能用了,仅在debug模式可以使用,以后需要自己单独处理。
静态资源要讲究动静分离。
本文地址:https://blog.jixiaob.cn/?post=40
版权声明:若无注明,本文皆为“赵苦瓜のBlog~”原创,转载请保留文章出处。
- 三星Active2 SM-R835U 破解心电图血压
- 【点滴记录】Java的初步入门(更新中)
- 【点滴记录】爬虫基础(urllib库、正则表达式)
- GrassCutter的配置和使用记录
- 【点滴记录】Django框架的入门 - 第六篇(模型迁移原理、模型关系、静态文件、文件上传、邮件发送)
- 【点滴记录】Python进阶——类和实例、面向对象
- 【点滴记录】MySQL的基本语法&&Python接入(pymysql)
- 使用Python写一个QQ机器人以图搜动漫图的插件接入SauceNAO ascii2d trace.moe animetrace
- Python与websocket——基于cqhttp的Grasscutter上下线通知机器人
- 【日常】瞎解包星穹铁道文件记录