Django基本命令
# 1. 下载Django
pip3 install django
# 2. 创建一个Django对象,在终端上执行,必须添加环境变量
django-admin.py startproject 项目名称
# 3. 项目文件目录
文件夹名称
manage.py // 与Django进行交互命令的脚本
// 全局文件
项目名称
wsgi.py // 与socket有关
settings.py // 配置文件 包含了项目的一些设置,包括数据库信息、调试标志以及其他一些工作的变量
urls.py // 路径与视图函数的映射关系
# 4. 项目与应用
一个项目有多个应用;
一个应用可以被多个项目拥有;
# 5. 创建django应用
python manage.py startapp appname
appname
models.py // 与数据库交互文件
views // 存放视图函数
# 6. 启动django项目
python3 manage.py runserver ip port
# 7. 迁移数据库
python manage.py makemigrations
python manage.py makemigrate
controller路由分配系统-URL
- 功能
客户端访问的url的路径(path)和视图函数的一一映射关系; - **语法格式*:
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
- 通过路径分组传参给视图函数
必须在对应的视图函数设置形参接收。- 无名分组
加圆括号,视图函数增加对应的形参即可接受此路径:url(r‘^(\d{4})/‘, f1),
,f1(request, year)
- 命名分组
若路径中存在多个参数,那么可以采用命名分组:url(r‘^(?P<year>\d{4})/(?P<month>\d{2})‘, find1),
- 无名分组
url命名
语法:
url(r"^register/", register, name=‘register‘),
前端<form action="{% url ‘register‘ %}" method="post">
作用: 若url路径有所修改,在前端就不需要进行任何调整,模板语言会根据url命名来转换成最新的url;- 路由应用分发
对于项目下有多个应用的话,可以将每个应用的urls分开来:url(r"^blog", include("blog.urls"))
别忘记配置根目录
url(r‘^$‘, views.index)
向server端传参数方式:
# 1. 通过路径,分组参数:
`<a href="localhost:8800/edit/1/"></a>`
`url(r‘^edit/(\d+)/, views.f)`
在view函数f中通过形参接收即可:`f(erquest, id)`;
# 2. 通过数据:域名/路径/?id=1, 通过reqeust.GET("id")可以取到id值;
视图函数-Views
// 两个对象:
请求对象: request
响应对象: Httpresponse("str")
// 两个请求方式
request.method: 请求方式;
request.GET: 存放get请求数据, 数据会放在path路径后,问号隔开,键值对
request.POST: 存放post数据;
// 两个方法
1. Httpresponse("str") # 返回实例字符串对象;
2. render(request, "html") # 模板渲染
1. 读取html的内容,传入Httpresponse实例化即可;
2. 渲染变量到html中:从后端取出数据,将数据键值对作为参数传入到html进行渲染;
```
def show_time(request):
import datetime
time = datetime.datetime.now()
return render(request, "time.html", {"time":time})
```
3. redirect(path) # 跳转
参数是url路径,随后调用对应的视图函数,与数据库交互取出变量,重新对html 进行渲染页面,并且跳转至目标路径下;
**注意**: render不会直接修改当前的路径,仅仅渲染一个html页面,但是redirect会直接修改当前的路径;
// 模板语言语法:
1. {{ } // 渲染变量
2. {% %} // 渲染标签
// 模板语言目的: 将变量嵌入到html中;
// 注意:只要带有模板语法的html都成为模板;
模板-Template
定义: 模板就是html加上逻辑代码, 为了更好地渲染变量
标签语法
标签for循环语句
{% for person in person_list %}
<p>{{person.name}}</p>
{% empty %) // 判断是否为空,内置标签判断
<p>没有符合的结果</p>
{% endfor %}
标签if判断语句
{% if i > 100 %}
<p>100</p>
{% else %}
<p>{{i}}</p>
{% endif %}
{% with %}
使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
标签循环计数
当前循环计数{{forloop.counter}}
变量语法
内置过滤器
相当于模板的内置函数;
{{ 变量|filter:参数 }}
# 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值
<p>default过滤器:{{ li|default:"如果显示为空,设置的解释性的内容" }}</p>
# 返回值的长度。它对字符串和列表都起作用
{{ value|length }}
# 如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d" }}
# 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
<p>截断字符:{{ content|truncatechars:20 }}</p>
<p>截断单词:{{ content|truncatewords:4 }}</p>
# safe保证页面的安全性,将变量内容转换成纯文本
<p>{{ label }}</p> <!--为了安全系统会把标签变成字符串-->
<p>{{ label|safe }}</p> <!--加上safe,确定你的数据是安全的才能被当成是标签-->
value="<a href="">点击</a>"
{{ value|safe}}
自定义过滤器(标签和变量)
- 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
- 在app中创建templatetags模块(模块名只能是templatetags)
- 在templatetags里面创建任意 .py 文件
from django import template
register = template.Library() #register的名字是固定的,不可改变
@register.filter // 自定义过滤器, 只能传一个参数
def multi(x,y):
return x*y
@register.simple_tag // 自定义标签, 可以传多个参数
def multitag(x,y,z):
return x*y*z
- 在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{% load my_tags %}
5、使用simple_tag和filter(如何调用)
-------------------------------.html
{% load xxx %}
# num=12
{{ num|multi:2 }} #24
{{ num|multi:"[22,333,4444]" }} 相当于复制了,把[22,333,4444]乘了num遍
{% multitag 2 5 6 %} 参数不限,但不能放在if for语句中 {% simple_tag_multi num 5 %}
自定义过滤器函数的参数只能两个,可以进行逻辑判断
自定义标签无参数限制,不能进行逻辑判断
{% if i|multi:5 > 1000 %} <!-- 判断i*5>1000 -->
<p>大于{{ i }}</p>
{% else %}
<p>大于等于{{ i }}</p>
{% endif %}
变量深度查询
# 方法1:
{{s.0}} //对于views传入的有序集合s,在模板语法中直接可以通过索引取出来
{{d.属性名}} //若传入的为键值对
{{obj_set.0.属性}} // 若传入的为对象的集合,也可以取出相应的属性
# 方法2:
双下划线;
模板继承
{% extends ‘base.html‘ %}
必须放在首行;- 覆盖父模板盒子中的内容:
{% block name %} 重新定制的代码 {% endblock %}
, 盒子越多越好,灵活性更好; - 取到父模板盒子的内容,然后再对其追加内容:
{{ block.super }}
; - 不允许盒子重名;
模型-model
# 若更改的model的属性,那么必须随之要重新运行数据库迁移命令;
数据库与ORM
对象关系映射
目的: 通过python的代码实现对数据库的增删改查;
在ORM中的对应关系:
表名 >>> 类名;
字段 >>> 类属性;
表的一条记录 >>> 类实例化对象
ORM之添加表记录
# 添加数据的两种方式
# 方式1:实例化对象就是一条表记录
Frank_obj = models.Student(name ="kate",course="python",birth="2000-9-9",score=80)
Frank_obj.save()
# 方式2:
models.Student.objects.create(name ="kate",course="python",birth="1995-5-9",score=88)
单表查询API
# 1、 all():查看所有
student_obj = models.Student.objects.all() // 打印的结果是QuerySet集合
# 2、filter():可以实现且关系,但是或关系需要借助Q查询实现, 查不到的时候不会报错
print(models.Student.objects.filter(name="Frank")) #查看名字是Frank的
print(models.Student.objects.filter(name="Frank",score=80)) #查看名字是Frank的并且分数是80的
# 3、get():如果找不到就会报错,如果有多个值,也会报错,只能拿有一个值的
print(models.Student.objects.get(name="Frank")) #拿到的是model对象
print(models.Student.objects.get(nid=2)) #拿到的是model对象
# 4、exclude():排除条件
print( models.Student.objects.exclude(name="kate")) #查看除了名字是kate的信息
# 5、values():是QuerySet的一个方法 (把对象转换成字典的形式了,)
print(models.Student.objects.filter(name="kate").values("nid","course")) #查看名字为kate的编号和课程
#打印结果:<QuerySet [{‘nid‘: 2, ‘course‘: ‘python‘}, {‘nid‘: 24, ‘course‘: ‘python‘}]>
# 6、values_list():是queryset的一个方法 (把对象转成元组的形式了)
print(models.Student.objects.filter(name="kate").values_list("nid", "course"))
#打印结果:< QuerySet[(2, ‘python‘), (24, ‘python‘)] >
# 7、order_by():排序,默认降序;
print(models.Student.objects.all().order_by("score"))
# 8、reverse():倒序, 先排序再反转;
print(models.Student.objects.all().reverse())
# 9、distinct():去重(只要结果里面有重复的)
print(models.Student.objects.filter(course="python").values("score").distinct())
# 10、count():查看有几条记录
print(models.Student.objects.filter(name="kate").count())
# 11、first()
# 12、last()
return render(request,"test.html",{"student_obj":student_obj})
# 13、esits:查看有没有记录,如果有返回True,没有返回False;并不需要判断所有的数据,
if models.Book.objects.all().exists():
双下划线之单表查询
# 获取id小于1 且 大于10的值
models.Tb1.objects.filter(id__lt=10, id__gt=1)
# 获取id等于11、22、33的数据
models.Tb1.objects.filter(id__in=[11, 22, 33])
# not in
models.Tb1.objects.exclude(id__in=[11, 22, 33])
# 名字包含ven的
models.Tb1.objects.filter(name__contains="ven")
# icontains大小写不敏感
models.Tb1.objects.filter(name__icontains="ven")
# 范围bettwen and
models.Tb1.objects.filter(id__range=[1, 2])
startswith,istartswith, endswith, iendswith
连表查询
基于对象的查询记录
修改
# 方法1
book = Book.objects.filter(id=id).first()
book.title=title
book.save()
# 方法2
Book.objects.filter(id=id).update(name=new_name)
查看数据库的sql语句(加在settings.py)
LOGGING = {
‘version‘: 1,
‘disable_existing_loggers‘: False,
‘handlers‘: {
‘console‘:{
‘level‘:‘DEBUG‘,
‘class‘:‘logging.StreamHandler‘,
},
},
‘loggers‘: {
‘django.db.backends‘: {
‘handlers‘: [‘console‘],
‘propagate‘: True,
‘level‘:‘DEBUG‘,
},
}
}
静态文件引入
1. 将所有静态文件放到一个static文件夹下;
2. 每个应用都应该有自己的静态文件夹;
3. `STATIC_URL = ‘/static/‘` 声明别名,`STATIC_ROOT = ( os.path.join(BASE_DIR, "bookSys/static") )`为实际路径, 只有用到别名那么都会到实际路径下寻找;
4. 在模板首行`{% load staticfiles %}`;
5. link rel="stylesheet" href={% static ‘css/bootstrap.css‘ %}";