原文转载于:https://blog.csdn.net/weixin_42149982/article/details/82390823
项目搭建
1.项目和应用的创建
# django-admin startproject 项目名 # python manage.py startapp 应用名
2.视图和模板初步使用
# 第一个参数为正则匹配,匹配成功时,执行第二个参数,即视图函数,例如: url(r"users/index", views.index) # 返回值 eturn HttpResponse("hello world") # 渲染模板,例如: return render(request, "index.html", context)
项目配置
1.常用配置项
# 路径 BASE_DIR # 该文件settings的路径为:/home/python/Desktop/python14/Django1/Django1/settings.py # os.path.abspath(__file__) 表示文件settings的路径 # os.path.dirname(os.path.abspath(__file__)) 表示该文件settings的文件夹路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # __file__指的就是当前文件 # DEBUG # 是否开启调试模式,项目上线时该为False # 设为True时,出错时会有提示信息 DEBUG = True # ALLOWED_HOSTS # 当DEBUG=False时,必须设定那些地址可以访问 # 允许那些ip或域名访问 # ALLOWED_HOSTS = ["127.0.0.1"] ALLOWED_HOSTS = ["*"] # 表示所有的ip都可以访问 # LANGUAGE_CODE = 'zh-hans' # 指定为中文 # TIME_ZONE = 'Asia/Shanghai' # 指定为上海时区
2.静态文件配置
# STATIC_URL:访问的url前缀,默认为:/static/ <img src="/static/images/66.jpg" alt="好看的图片"> # STATICFILES_DIRS:静态文件保存在哪个目录下,例如, STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files')] # 访问静态文件前缀 ,例如,访问图片的时候地址为:/static/images/66.jpg,会去到'static_files文件夹下去找 STATIC_URL = '/static/' # 指定静态文件保存在那个文件夹下,绝对路径 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files')]
3.URL配置
# 项目的urls.py # 第一个参数:正则匹配,匹配成功,执行后面的,进行二次匹配 # 对输入的网址进行匹配,匹配成功之后会把匹配到的部分切掉,把剩余的部分交个下面的进行二次匹配 url(r"^users/", include("users.urls")) # 应用的urls.py urlpatterns = [ # 对剩余的部分进行匹配,匹配成功后,执行后面视图函数 url(r"^index$", views.index) ] # 匹配流程 1.域名、端口、端口后的 /,以及查询字符串(问号后面的键值参数)不参与匹配 2.先到项目下的 urls.py 进行匹配,再到应用的 urls.py 匹配 3.根据url配置的先后顺序,从上到下进行URL匹配 4.在项目下匹配成功的URL部分会去掉,剩下的部分继续到应用下作匹配 5.如果匹配成功,Django会调用对应的视图函数,返回响应内容给浏览器显示 6.如果最终匹配不成功, Django 会给浏览器返回404错误 # 捕获URL中的参数 未命名参数:按位置传递 url(r"^news/(\d+)/(\d+)$", views.news),视图函数 def news(request, a, b): return HttpResponse("news: %s %s" % (a, b)) 命名参数:按名字传递 url(r"^news/(?P<category>\d+)/(?P<page_no>\d+)$", views.news) def news(request, category, page_no): return HttpResponse("news: %s %s" % (category, page_no))
状态保存
1.cookie
# 保存cookie:使用响应对象 response.set_cookie('user_id', 10) # 读取cookie: 使用request对象 request.COOKIES.get('user_id') # 删除cookie response.delete_cookie("user_id") # 有效期:关闭浏览器
2.session
# session工作原理 django默认保存session到数据库表中 一条记录保存一个浏览器(一个用户)的所有的session键值对数据 通过sessionid来区分不同的浏览器(不同用户) # 通过session保存和读取数据 保存:request.session['键']=值 读取: request.session.get('键') # 删除命令session # 删除一个sessoin键值对(注意:键不存在会报错 `KeyError`) del request.session['键'] # 清除当前访问用户所有的session数据 request.session.flush() # 删除一条表记录 request.session.clear() # 清空字段中的session键值对数据 # 设置session数据有效时间; 如果不设置,默认过期时间为两周 request.session.set_expiry(value) 如果value是一个整数,则 session数据 将在value秒没有活动后过期 如果value为0,则 session数据 将在用户 关闭浏览器时过期 如果value为None,则 session数据 将在 2周后过期
配置保存session数据到redis中
修改settings.py文件,新增如下选项: # django项目的缓存配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", # 表示选的是redis里序号1的,select 1 "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": "" } } } # session数据缓存到Redis中 SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default"
类视图
1.类视图使用装饰器&method_decorator
# 类视图使用装饰器&method_decorator method_decorator装饰器作用:为函数装饰器补充第一个self参数,以便让装饰器能应用到方法中。例如,在方法上@method_decorator(check_ip),# check_ip为装饰函数 在类上,@method_decorator(check_ip, name="dispatch"),表示所有的请求都有该装饰器的功能,所有的请求方式都会经过dispatch函数
2.多继承应用&Mixin扩展类
# 定义一些共同的类,这些类,这些类有一些功能,然后继承,在调用复用父类的方法,给该类视图添加功能
中间件
1.Django中间件使用
# 继承MiddlewareMixin类,重写process_request和process_response方法 # 在setting文件中注册中间件类 MIDDLEWARE = [ 定义中间件的路径],例如, 中间件引用:'users.views.MyMiddleWare', copy reference 拷贝其路径
2.多个中间件执行顺序问题
# 对process_request方法,先注册的中间件会先执行 在视图执行之前调用,注意:该方法可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了,可以进行一些拦截操作 # 对process_response方法,后注册的中间件会先执行 必须要有返回值
模板
1.静态模板
def index(request): context = {"name": "zs"} # index.html需要的数据。字典格式 # 得到其模板对象 template = loader.get_template("index.html") # type: Template # 渲染得到字符串 template_str = template.render(context) # 生成好的静态模板 return HttpResponse(template_str)
2.模板语法
2.1 for循环
{% for item in 列表 %} {{forloop.counter}} <1-- 表示当前是第几次循环,从1开始 --> {{forloop.counter0}} <!-- 表示当前是第几次循环,从0开始 --> {% empty %} 列表为空或不存在时执行此逻辑 {% endfor %}
2.2 过滤器
# 变量 | 过滤器:参数,例如,default,默认值,如果变量不存在时则返回默认值。 data | default:'默认值' # 自定义过滤器 1.在应用user下,创建templatetags目录,然后在里面创建一个custom_filters.py 文件 2.然后在settings文件里的INSTALLED_APPS 中注册templatetags,即'users.templatetags' 3.在custom_filters.py里写一下功能,例如, from django import template register = template.Library() @register.filter(name="sumNum") # 过滤器名字 def sumNum(value, arg): # value | 过滤器:arg sum_num = 0 for num in value: sum_num += num return sum_num 4.index.html里用该过滤器,首先{% load custom_filters %} 然后,就可以使用了该过滤器,例如, {{ my_num | sumNum:None}} # my_num对应的是value,None对应的是arg
2.3 模板继承
# 父模板 {% block 块名称 %} 预留区域,可以编写默认内容,也可以没有默认内容 {% endblock %} # 子模板 {% extends "父模板路径" %} {% block 名称 %} # 父模板里的名称,重写 子模板的内容 {{ block.super }} 显示父模板中block的内容 {% endblock %}
数据库
1.数据库配置
# 在setting文件中配置数据库(主机,端口,用户名,密码等)DATABASES DATABASES = { 'default': { # 配置使用mysql 'ENGINE': 'django.db.backends.mysql', # 数据库产品 'HOST': "localhost", # 数据库ip 'PORT': 3306, # 数据库端口 'USER': "root", # 用户名 'PASSWORD': "mysql", # 密码 'NAME': "db_django01", # 数据库名 } } # 在项目同名包下即Django01的__init__文件中,导入并安装pymysql模块 import pymysql pymysql.install_as_MySQLdb()
2.模型类定义
# 模型类需要继承models.Model 类 # 在模型类中定义属性,格式如下: 属性名 = models.字段类型(字段选项) # 一对多关联属性定义:使用ForeinKey定义在多的一方,例如: department = models.ForeignKey('Department')
3.执行迁移命令,终端下输入命令
# 生成迁移文件: python manage.py makemigrations # 生成表: python manage.py migrate # 表头发生改变就需要迁移,表里的内容发生改变不需要进行迁移
4.模型管理器(objects类属性)
# 方法 get 查询唯一的一条数据 如果查到多条数据,则报错:MultipleObjectsReturned 如果查询不到数据,则报错:DoesNotExist all:查询所有数据 filter:条件查询 ,返回查询集 exclude: 查询排除某个条件之外的数据 order_by: 返回经过排序后的查询集
5.数据增删改
# 新增 # 第一种 Department.objects.create(name="zs") # 第二种 模型对象.save() # 删除 Department.objects.filter(查询条件).delete() 模型对象.delete() on_delete选项,外键 默认值为models.CASCADE,当删除部门时,会删除相关联的员工 department = models.ForeignKey('Department', on_delete=models.CASCADE) 如果不想删除关联数据,可设置on_delete为 PROTECT department = models.ForeignKey('Department', on_delete=models.PROTECT) # 更新 # 第一种 Department.objects.filter(查询条件).update(name='人事部') # 第二种 模型对象.save()
6.查询
# 模型类.objects.filter(模型类属性名__条件名 = 值) # F对象 在设置查询条件时,要比较表中的两个字段 # Q对象 在查询条件之间作逻辑操作(与或非) # 聚合函数:aggregate Sum, Count, Max, Min, Avg 返回值是字典 # 关联查询 一查多 通过对象实现:一类对象.多类名小写_set.all() 通过模型类实现: d = Department.objects.get(name=‘研发部’) d.employee_set.all() Department.objects.filter(employee__name__exact='赵小二') 多查一 通过对象实现:多类对象.关联属性 通过模型类实现: e = Employee.objects.get(name='赵小二') e.department Employee.objects.filter(department02__name__exact='研发部') # order_by方法:排序 # 查询集QuerySet 查询集的方法 get, all, count, filter, exclude, order_by, aggregate, exists 限制查询集
admin站点管理
# 配置使用Admin站点管理模型类数据 创建超级用户: python manage.py createsuperuser 注册模型类:# users/admin.py: from users.models import Department, Employee admin.site.register(Department) admin.site.register(Employee) # 使用ImageField字段,实现通过adimin站点上传图片 class Department(models.Model): ... class Meta: ... verbose_name = '部门' verbose_name_plural = verbose_name # 去掉复数的s # 上传图片 使用Admin站点保存图片,需要安装Python的图片操作包 pip install Pillow # settings.py MEDIA_ROOT=os.path.join(BASE_DIR,"media") # 用户头像 avatar = models.ImageField(upload_to='users', null=True) upload_to 指定该字段的图片保存在MEDIA_ROOT目录中的哪个子目录下