目录
生成django工程项目文件
django-admin startproject djweb 生成djweb项目
django-admin startapp news 生成news应用
配置models文件
class NewInfo(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
b_date= models.DateField()
read = models.IntegerField()
插入数据,进入交互环境
python manage.py shell
In [1]: from news.models import NewInfo
In [2]: NewInfo.objects.all()
Out[2]: <QuerySet []>
# 查询为空,这时插入数据
In [11]: n1= NewInfo()
In [12]: n1.title = 'title1'
In [13]: n1.read = 999
In [14]: n1.b_date= '2024-01-01'
In [15]: n1.save()
In [20]: res = NewInfo.objects.all()[0]
In [21]: res.title # 保存成功
Out[21]: 'title1'
配置admin文件
from .models import NewInfo
# Register your models here.
admin.site.register(NewInfo)
创建超级用户
python manage.py createsuperuser
用户名 (leave blank to use 'pass'): pass
电子邮件地址: xxx@qq.com
Password:
Password (again):
密码跟 用户名 太相似了。
密码长度太短。密码必须包含至少 8 个字符。
这个密码太常见了。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
启动项目
python manage.py runserver
访问web页面:http://127.0.0.1:8000/admin
点击增加信息:
展示中文信息及调整时区
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
点击删除信息:
自定义admin模型类展示数据
class NewInfoAdmin(admin.ModelAdmin):
# 自定义模型类
list_display = ['id','title','b_date','read']
# 自定义模型定义到系统中
admin.site.register(NewInfo,NewInfoAdmin)
展示结果:
总路由分配
from django.contrib import admin
from django.urls import path,re_path,include
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^news/',include('news.urls'))
]
子路由配置:
from .views import home
urlpatterns = [
path('home/',home),
]
debug模式调试代码
关闭原有terminal进程,点击debug模式,选择红色按钮断点,此时刷新web页面的访问url地址.
templates模板配置
# 项目目录位置的模板
# 'DIRS': [],
'DIRS': [BASE_DIR / 'templates'],
msyql数据库配置
mysql> create database djweb charset = utf8;
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> exit
Bye
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djweb',
'USER':'root',
'PASSWORD':'****',
'HOST':'localhost',
'PORT':3306
}
}
ORM常用字段类型
- AutoField
- BooleanField
- CharField
- TextField
- DecimalField
- TimeField
- DateTimeField
- FileField
常用字段选项
- default
- primary_key
- unique
- db_index # 索引
- null
- blank
- verbose_name # web可读
- help_text
关系字段类型(一对一、一对多、多对多、自定义关联)
ForeignKey :一对多,将字段定义在多的一方中
goods = models.ForeginKey('Goods',on_delete=models.CASCADE)
ManyToManyField: 多对多
users = models.ManToManyField('Users',on_delete=models.CASCADE)
OneToOneField:一对一
goods = models.OneToOneField('Goods',on_delete=models.CASCADE)
自定义关联:使用self指定
goods = models.ForeginKey('self',null=True,blank = True)
goods = models.ManyToManyField('self',null=True,blank = True)
多对对模型类实践案例
class NewInfo(models.Model):
title = models.CharField(max_length=30,verbose_name='标题',help_text="标题")
content = models.TextField(max_length=30,verbose_name="内容",help_text='内容')
# b_date= models.DateField()
read = models.IntegerField(verbose_name='阅读量',help_text='评论数量')
type = models.ManyToManyField('NewsType',verbose_name='新闻类型',help_text='类型')
class NewsType(models.Model):
name = models.CharField(max_length=20,verbose_name='名称')
元选项Meta配置
class Meta:
# 自定义表名,若无此设置默认为表名:应用名+模型类小写
db_table = 'news'
verbose_name = '新闻类型' # 后台可以看到
结果实例:
魔术方法__str__应用
def __str__(self): # 魔术方法 -- 更改对象显示的内容
return self.name
模糊条件查询
- xxx.objects.filter(模型类名__条件名 = 值)
- xxx.objects.filter(name__contains='xxx')
- xxx.objects.filter(name__startswith='xxx')
- xxx.objects.filter(name__endswith='xxx')
- xxx.objects.filter(name__in=[1,2,3])
比较条件查询
- xxx.objects.filter(id__gt=1) # 大于
- xxx.objects.filter(id__lt=1) # 小于
- xxx.objects.filter(id__gte=1) # 大于等于
- xxx.objects.filter(id__lte=1) # 小于等于
F对象与Q对象
from django.db.models import F,Q
- F对象用于类属性比较 eg: xxx.objects.filter(read__gte=F('comment'))
- Q对象用于逻辑与或非(&|~) eg: xxx.objects.filter(Q(read__gte=40) & Q(comment__gt=30))
聚合函数
from django.db.models import Sum,Avg,Max,Min
eg: xxx.objects.all().aggregate(Sum('read'))
- Sum
- Count
- Avg
- Max
- Min
查询和对象关联的数据获取方式
一到多查询:
data = xxx.objects.get(id=1)
data.newinfo_set.all() # 模型类名小写+_set实现
多到一查询:
data = xxx.object.get(id=1)
data.title # 通过关联的对象直接获取对应的数据
由一模型类查询多模型类数据
语法: 关联模型类名小写__属性名__条件运算符=值
data=xxx.objects.filter(类名小写__属性名__contains='q') # 查询某一属性包含q的字段
由多模型类查询一模型类数据
语法: 一模型类名小写__一模型类属性名__条件运算符=值
data=xxx.objects.filter(类名小写__属性名='yyy') # 查询属性为yyy的所有字段
data=xxx.objects.filter(类名小写__属性名__gt=10) # 查询其属性值大于10的所有字段
关联过滤查询
# ⼀对应的模型类关联对象的id
# 多对应的模型类对象.关联类属性_id
# 语法
模型类对象 = 模型类.objects.get(id=1)
模型类对象.关联属性_id
ORM增删改查操作
- 修改数据: 查到要修改的对象,直接修改字段xxx.title='yyy',save()方法保存
- 增加数据: xxx.属性值=特定值, xxx.save()保存
- 删除数据: 获取data = xxx.objects.all(),然后data.delete()直接删除
路由参数匹配
- 位置参数:
re_path(r'^index/(\d+)/$',views.show) # 直接使用小括号
- 关键字参数:
re_path(r'^index/(?P<name1>\d+)/$',views.show)
requests对象的属性
- path
- method
- encoding
- GET # ?'key1'='value1'&'key2'='value2'
- POST
- FILES
- COOKIES
- session
HttpResponse对象
- content
- charset
- status_code
- content-type
常用方法
set_cookie(key,value='',max_age=None,expires=None)
# max_age 整数,指定过期时间
# expires 指定日期的特定过期时间
# 上面二选一,若无指定关闭浏览器时cookies会过期
eg:
response = HttpResponse(res_list,status)
response.set_cookie('token','xxx',max_age=4)
response.delete_cookie('token')
session的操作
- request.session['key']='value'
- request.session.get('key',None)
- request.session.clear() # 清除所有session数据
- request.session.flush() # 清除存储中的整条数据
- del request.session['key']
- request.session.set_expiry(value) # 设置会话的超时时间
类视图的url配置方式
# views.py
from django.views import View
class NewsView(View):
def get(self,request):
pass
def post(self,request):
pass
# urls.py
re.path(r'news/$',views.NewView.as_view())
模板变量
语法:{{ 变量 }}
顺序解析dict.title:
- 字典dict['title'] 先属性后方法,若无此属性,再查询对应方法
- 若格式dict.0则解析为列表dict[0],若变量不存在则为空字符串
模板标签for、if
语法:{% xxx %}
for标签
{% for x in xxx %}
{{forloop.counter} # 表示当前第几次循环,从1开始
{% empty %} # 列表为空或不存在时执行该逻辑
{% endfor %}
if标签
{% if ... %}
{% elif ... %}
{% else %}
{% endif %}
过滤器 lower、upper
语法:{{ 管道符号 | 过滤器 }} eg:{{ xxx | lower}}
- {{ xxx | upper }}
- {{ xxx | lower }}
- {{ xxx | add:2 }}
- {{ datex | date:'y-m-d' }}
父模板
{% block xxx %}
{% endblock xxx %}
子模板
{{% extends '父路径path'%}}
{% block xxx %}
{% endblock xxx %}
中间件的函数
# 初始化
def __init__(self):
pass
# 处理请求前
def process_request(self,request):
pass
# 处理视图前
def process_view(self,request,func,*args,**kwargs):
pass
# 处理视图后
def process_response(self,request,response):
pass
# 处理异常
def process_exception(self,request,exception):
pass
自带认证方式登录验证
from django.contrib.auth import authenticate
username = request.POST['name']
password = request.POST['passwd']
user = authenticate(request,username=username,password=password)
if not user:
pass
django-redis的配置
参考官方网址:django-redis 中文文档 — Django-Redis 4.7.0 文档
# 配置django-redis
CACHES = {
"default": { # 预留
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"session": { # 用于保存session的数据
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"
日志器的配置使用
参考官方网址:Logging | Django documentation | Django
# setting
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 是否禁用已经存在的日志
'formatters': { # 日志信息显示的格式
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'filters': { # 对日志进行过滤
'special': {
'()': 'project.logging.SpecialFilter',
'foo': 'bar',
},
'require_debug_true': { # django在debug模式下才输出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理方法
'console': { # 向终端中输出日志
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { # 向文件中输出日志
'level': 'DEBUG',
'class': 'logging.FileHandler',
# 'filename': '/path/to/django/debug.log', # 放到固定位置
'filename': os.path.join(BASE_DIR,'logs/name.log'),# 日志文件的位置
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['special']
}
},
'loggers': { # 日志器
'django': { # 定义一个名为django的日志器
'handlers': ['console'], # 向终端中输出日志
'propagate': True,
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'myproject.custom': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO', # 日志器接收的最低日志级别
'filters': ['special']
}
}
}
# view
import logging
# Get an instance of a logger
logger = logging.getLogger('django')
# output log
logger.debug('debug')
logger.info('info')
logger.error('error')
日志等级的划分
- FATAL/CRITICAL 危险
- ERROR 错误
- WANGING 警告
- INFO 信息
- DEBUG 调试
- NOTEST