Python-Django之MTV模型(反向解析+模板+模型)
来自:pixiv 画师( キューソ猫神 )
- 目录
- MTV概念模型
- 环境准备
- urls
- views
- template
- model
MTV模型
Django的MTV分别代表:
Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM)。
Template(模板):放所有的html文件模板语法:目的是将白变量(数据库的内容)如何巧妙的嵌入到html页面
View(视图):负责业务逻辑,并在适当的时候调用Model和Template。
此外,Django还有一个URL分发器。它的作用是将一个个URL的页面请求分别发给不同的Views处理,Views再调用相应的Model和Template。
模型图
环境
Anaconda3+Pycharm(内置Django)
django项目启动命令:
python manage.py runserver 8080
urls
绑定请求路径与函数
url(r"^[路径]",views.[函数]) #适用正则匹配
path("[路径]",views.[函数])
正则补充:
^:以xx开始
$:以xx结束
():无命名分组
(?P<name>):命名分组
引入其他urls文件:
url(r"^[路径]",include("[文件路径]"))
path("[路径]",include("文件路径"))
views
写入与url绑定的函数
默认参数:request
request下的方法:
path 请求路径 get_full_path 全路径 method 请求方法(GET,POST) user 当前登录用户 session 会话对象,可读写 cookies 标准python字典对象
返回值:
httpResponse:字符串 render:html render(request,"xx.html",locals()) render(request,"xx.html",{局部变量}) render_to_response:等同于render少request参数 redirect:重定向到另一个请求路径或另一个网站 redirect("/[请求路径]/") redirect("[网址]")
template
Template=html+python逻辑代码
1.模板语法
html引入static文件方式:
#方式一
<script src="/static/jquery.js"></script>
#方式二
{% load staticfiles %}
<script src="{% static 'jquery.js' %}"></script>
#加入settings文件:
STATICFILES_DIRS=(
os.path.join(BASE_DIR, "blog/static"),
)
template变量:
引用变量>>
语法:{{ name }}
变量类型:str,list,dict,class
原理:
#>>>>>>进入django环境 python manage.py shell t=Template('hello {{ name }}') c=Context({'name':'alex'})) t.render(c) #!一个模板多次渲染更高效!
变量过滤器>>
过滤器add:{{ dic.age|add:100 }}
过滤器capfirst:{{ str|capfirst}}
过滤器cut:{{ str|cut:' ' }}
过滤器date:{{ Time|date:'Y-m-d' }}
过滤器default:{{ li2|default:"空" }}
过滤器default_if_none:{{ li3|default_if_none:'为none' }}
过滤器safe:{{ a|safe }}
等同于{% autoescape off%}
{{ a }}
{% endautoescape %}
过滤器first:{{ str|first }}
过滤器length:{{ str|length }}
过滤器slice:{{ str|slice:"2" }}
template标签(tag):
#if: {% if 条件 %} 执行语句 {% elif 条件 %} 执行语句 {% else %} 执行语句 {% endif %} #for: <ul> {% for obj in list %} <li>{{ obj.name }}</li> {% endfor %} </ul> #csrf: django在post第一次提交表单时的安全验证,防止csrf(跨站请求) form标签中加入{% csrf_token %}解除 #with: 将后台传出的变量起个别名 {% with six=qeqqhetqtqej %} {{ six }} {% endwith %} #verbatim: 禁用render {% verbatim %} {{ age }} {% endverbatim %} #load: 加载标签库(自定义filter,simple_tag) 步骤: #①在app中创建templatetags包 #②包下创建xx.py文件,内容: from django import template from django.utils.safestring import mark_safe #register的名字是固定的,不可改变 #filter @register.filter() def filter_multi(x,y): return x*y #simple_tag @register.simple_tag() def simple_tag_multi(x,y,z): return x*y*z` #③html引入自定义tag:{% load [xx.py] %} #④使用 {{ var|[函数名]:value% }} {% [函数名]:var var var %} #filter与simple_tag区别: filter只能传一个参数,simple_tag可以传多个参数 filter可以在if等后使用,simple_tag不可以
2.1模板继承标签
目的:减少代码的冗余
语法:
{% block classinfo %}
{% endblock %}
使用步骤:
#1、创建一个基板文件base.html
#2、放入重复出现的代码
#3、在有差异的代码段加(一个基板文件可以有多段block)
{% block classinfo %}
xxx(可以留空)
{% endblock %}
#4、其他的html继承这个基板(继承后会自动调用父类下的xxx,可以被多个html继承)
{% extends "base.html" %} #必须是在文件的第一行
#其他不同的代码放入这个盒子
{% block classinfo %}
***不同的代码***
{% endblock%}
2.2模板添加标签
使用步骤:
#在需要的地方include文件内容
{% include 'xxx.html' %}
model
数据库模型—-ORM:对象关系映射
ORM功能:操作表、操作字段
QuerySet特征:
QuerySet相当于sql语句,不调用时不执行
QuerySet有缓存,更改查询条件需要重新赋值
单表操作:(一对一)
1、创建
#①models.py:写入对应数据库表的类
class Book(models.Model):
name=models.CharField(max_length=20)
price=models.IntegerField()
pub_date=models.DateField()
#②setting.py:修改默认数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'd1101', #生成的数据库表名
'USER':'root',
'PASSWORD':'root',
'HOST':'localhost',
'PORT':'3306',
}
}
#③ 修改默认驱动:!默认驱动MySQLdb不支持python3!
#工程文件__init__.py添加:
import pymysql
pymysql.install_as_MySQLdb()
#④创建:
命令:
python manage.py makemigrations #创建脚本
python manage.py migrate #迁移
#!PyMySQL 0.9.3与Django 2.2不兼容问题!
#创建后报错,通过报错信息进入base.py:(注释掉如下两行:35/36行)
if version < (1, 3, 3):
raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
#再次创建,再次报错,通过报错信息进入operations.py文件(46行):
query.decode替换为query.encode
#创建迁移,完成生成
⑤修改(可选):
#如需修改对应数据的类,再次创建迁移即可
2、增删改查
增:
#方式一
b=Book(name='php',price=59,pub_date='2019-01-09',author='alex')
b.save()
#方式二
Book.objects.create(name='php',price=59,pub_date='2019-01-09',author='alex')
#其他:字典方式传入
Book.objects.create(**dic)
改:
#方式一
Book.objects.filter(author="egon").update(price='99')
#方式二
b=Book.objects.get(author="egon")
b.price=100
b.save()
删:
Book.objects.filter(id=1).delete()
查:
#全部
Book.objects.all()
#切片
Book.objects.all()[:1]
#步长
Book.objects.all()[::2]
#首
Book.objects.first()
#末
Book.objects.last()
#指定条件,单行
Book.objects.get(id=2)
#指定字段的某个属性
Book.objects.filter(id=2).values("name")
# 指定字段的某些属性
Book.objects.filter(id=2).values_list("name","price")
#排除条件
Book.objects.exclude(id=2).all()
#去重
Book.objects.all().distinct()
#计数
Book.objects.all().count()
#万能的
Book.objects.filter(price__gt=50).all()
Book.objects.filter(name__contains="p").all()
多表查询:(一对多)[表关系:外键]
查:
#方式一(了解)
publish_obj=Publish.objects.filter(city='南京')[0]
Book.objects.filter(publish=publish_obj)
#原理上等同于>>
pid=Publish.objects.get(city='南京').id
Book.objects.filter(publish_id=pid)
#方式二(了解)
Publish.objects.filter(city="南京")[0].book_set.all()
#方式三(常用)
book_list = Book.objects.filter(publish__city='南京')
增:
#方式一
publish_obj = Publish.objects.filter(id=1)[0]
Book.objects.create(name='jq',price=67,author='alex',pub_date='2019-01-09',publish=publish_obj)
#方式二
Book.objects.create(name='java',price=67,author='alex',pub_date='2019-01-09',publish_id=1)
多表查询:(多对多)[表关系:ManyToMany]
#查:
#查询书的所有作者
author_list=Book.objects.get(id=3).author.all()
#等同于
author_list = Author.objects.filter(book__name='php')
#增:
#书增加作者
Book.objects.get(id=3).author.add(Author.objects.get(id=3))
#等同于
Book.objects.get(id=3).author.add(3)
#删:
#删除书的作者
Book.objects.get(id=3).author.remove(Author.objects.get(id=3))
#等同于
Book.objects.get(id=3).author.remove(3)
跨表查询:
#聚合查询:
Book.objects.all().aggregate(Avg('price'))
Book.objects.all().aggregate(Sum('price'))
Book.objects.all().aggregate(Max('price'))
Book.objects.filter(author__name='alex').aggregate(alex书的数量=Count('id'))
#分组查询:
Book.objects.values('author__name').annotate(Count('name'))
Book.objects.values('author__name').annotate(Sum('price'))
#FQ查询:
#F:将字段值与某个常量做算数、比较操作
Book.objects.all().update(price=F('price')+10)
Book.objects.filter(price__gt=90)
#Q:构建条件搜索(与&或|非~);可以组合关键字查询
Book.objects.filter(Q(price=55)&~Q(author__name='alex'))
Book.objects.filter(~Q(author__name='alex'),price=55)