在Django中,所有的Queryset都是惰性的,意思是当创建一个查询集的时候,并没有跟数据库发生任何交互。因此我们可以对查询集进行级联的filter等操作,只有在访问Queryset的内容的时候,Django才会真正进行数据库的访问。而多频率、复杂的数据库查询往往是性能问题最大的根源。
不过我们实际开发中,往往需要访问到外键对象的其他属性。如果按照默认的查询方式去遍历取值,那么会造成多次的数据库查询,效率可想而知。
在查询对象集合的时候,把指定的外键对象也一并完整查询加载,避免后续的重复查询。
1,select_related
适用于外键和多对一的关系查询;
2,prefetch_related
适用于一对多或者多对多的查询。
会话跟踪技术,保留用户
Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。
具体一个浏览器针对一个服务器存储的key-value({ })
response.set_cookie("is_login",True)
request.COOKIES.get("is_login")
Session是服务器端技术,利用这个技术,服务器在运行时可以 为每一个用户的浏览器创建一个其独享的session对象,由于 session为用户浏览器独享,所以用户在访问服务器的web资源时 ,可以把各自的数据放在各自的session中,当用户再去访问该服务器中的其它web资源时,其它web资源再从用户各自的session中 取出数据为用户服务。
request.session['username']="kobe"
request.session.set_expiry(7*24*3600) # 设置session过期时间为一周后
username=request.session.get('age','')
request.session.flush()
FBV(function base views)就是在视图函面使用函数处理请求
CBV(class base views)就是在视图里面使用类处理请求
python manage.py makemigration 子应用名
python manage.py migrate
request.get:查询字符串参数
request.post:form表单参数
request.body:非表单数据
request.FILES:个类似于字典的对象,包含所有的上传件
request.user:请求用户
request.path:请求url
request.method:请求方式
重点:描述抽象模型类
serializer.is_valid()
惰性执行、缓存。
使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数
新建一个查询集对象就可以实现
all()
filter()
exclude()
order_by()
HttpResponse,
JsonResponse,
redirect
在HttpRequest对象中, GET和POST属性是django.http.QueryDict类的实例。
QueryDict类似字典的自定义类,用来处理单键对应多值的情况。
在 python 原始的字典中,当一个键出现多个值的时候会发生冲突,只保留最后一个值。而在 HTML 表单中,通常会发生一个键有多个值的情况,例如 (多选框)就是一个很常见情况。
primary_key
设置为True时,字段可以为空。设置为False时,字段是必须填写的。字符型字段CharField和TextField是用空字符串来存储空值的。如果为True,字段允许为空,默认不允许。
设置为True时,django用Null来存储空值。日期型、时间型和数字型字段不接受空字符串。所以设置IntegerField,DateTimeField型字段可以为空时,需要将blank,null均设为True。
router=routers.SimpleRouter()
router.register('project',视图类)
urlpatterns=[
path('',include(router.urls))
]
Django在创建对象时在掉用save()方法后,ORM框架会把对象的属性转换为写入到数据库中,实现对数据库的初始化;通过操作对象,查询数据库,将查询集返回给视图函数,通过模板语言展现在前端页面
django-admin startproject django_project 创建一个项目
python manage.py runserver 运行项目
python manage.py startapp 子应用名 创建子应用
python manage.py makemigrations 子应用名 创建迁移脚本
python manage.py migrate 生成迁移脚本
python manage,py createsuperuser 创建管理员用户
python manage.py shell 终端调试代码
python manage.py startapp users
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders', # 同源策略
'rest_framework',
'drf_yasg', # 生成接口文档子应用
'django_filters', # DRF过滤器子应用
'users',
]
pip install djangorestframework-jwt
REST_FRAMEWORK = {
# 指定搜索引擎类
'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter', ],
# 'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend'],
# 'SEARCH_PARAM': 'se',
# 指定分页引擎类
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 3,
# 指定用于支持coreapi的Schema
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
# 指定使用的认证类
# a、在全局指定默认的认证类(认证方式)
'DEFAULT_AUTHENTICATION_CLASSES': [
# 1、指定jwt token认证
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
],
}
urlpatterns = [
path('admin/', admin.site.urls),
re_path('',include('projects.urls')),
path('docs/',include_docs_urls(title='接口测试平台API文档',description='这个是接口平台的文档')),
re_path(r'^swagger(?P.json|.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), # <-- 这里
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), # <-- 这里
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), # <-- 这里
path('user/',include('users.urls'))
]
urlpatterns=[
path('',include(router.urls)),
re_path(r'^(?Pw{6,20})/count/$', views.UsernameIsExistedView.as_view()),
re_path(r'^(?P[A-Za-z0-9一-龥]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+)/count/$',
views.EmailIsExistedView.as_view()),
path('login/', obtain_jwt_token),
]
def jwt_response_payload_handler(token,user=None,response=None):
return {
'user_id':user.id,
'username':user.username,
'token':token
}
# JWT配置
JWT_AUTH = {
# 指定token失效时间为1天
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
# 使用自己的jwt_response_payload_handler,目的是响应结果中可以返回用户名和id
'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.handle_jwt_response.jwt_response_payload_handler',
}
REST_FRAMEWORK = {
...
...
...
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day', # 匿名用户
'user': '10/day'
}
}
utils----->throttle_class.py,定义CustomAnonRateThrottle(随意),但是必须继承UserRateThrottle
UserRateThrottle:表示正对登录用户的
from rest_framework.throttling import UserRateThrottle
class CustomAnonRateThrottle(UserRateThrottle):
THROTTLE_RATES = {"user": "5/day"}
from utils.throttle_class import CustomAnonRateThrottle
class ProjectsViewSet(viewsets.ModelViewSet):
queryset=Projects.objects.all()
serializer_class = ProjectsSerializer
pagination_class = PageNumberPagination
permission_classes = [permissions.IsAuthenticated]
throttle_classes = [CustomAnonRateThrottle]
def list(self, request, *args, **kwargs):
response=super().list(request, *args, **kwargs)
for item in response.data['results']:
item['interfaces']=Interfaces.objects.filter(project_id__exact=item['id']).count()
item['testsuits']=Testsuits.objects.filter(project_id__exact=item['id']).count()
item['testcases']=Testcases.objects.filter(interface__project_id__exact=item['id']).count()
item['configures']=Configures.objects.filter(interface__project_id__exact=item['id']).count()
return response
values : 取字典的queryset
values_list : 取元组的queryset