Django 项目相关技术点汇总
rest framework 序列化
首先想到的是,写restful接口,操作数据库 urls文件
from rest_framework.routers import DefaultRouter
from .views import yyyEdit
urlpatterns=[]
# 创建路由对象
routers = DefaultRouter()
# 通过路由对象对视图进行路由生成
routers.register('yyy',yyyEdit)
urlpatterns += routers.urls
对应的views
from .models import yyy
from .serializers import yyy_Serializers
from rest_framework.viewsets import ModelViewSet
# Create your views here.
class yyyEdit(ModelViewSet):
queryset = yyy.objects.all()
# 序列化
serializer_class = yyy_Serializers
serializers内容
from rest_framework import serializers
from .models import yyy
class yyy_Serializers(serializers.ModelSerializer):
class Meta:
model = yyy
fields = '__all__'
最后在总视图中添加这个应用中的urls
path('api/', include('应用名.urls'))
jwt认证
原理很简单,客户端输入用户密码,获取token
服务端签发时,获取用户名&密码,通过加SALT,生成token,token分为3个部分
- headers部分
- payload部门
- signature部分
Token部分
from django.contrib.auth.models import User, AnonymousUser
from rest_framework.authentication import BaseAuthentication
from django.utils.deprecation import MiddlewareMixin
from rest_framework.exceptions import AuthenticationFailed
from django.shortcuts import redirect
import jwt
from django.conf import settings
import datetime
from jwt import exceptions
###生成Token
def GetJwtToken(username, password):
userobject = User.objects.filter(username=username).first()
if not userobject:
return False
else:
if not userobject.check_password(password):
return False
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
payload = {
"username": username,
"exp": datetime.datetime.utcnow() + datetime.timedelta(days=7)
}
SALT = settings.SECRET_KEY
token = jwt.encode(
payload=payload,
key=SALT,
algorithm="HS256"
)
return token
Token校验
class QtsAuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
user = AnonymousUser()
try:
token = request.COOKIES['token']
except Exception as e:
user = AnonymousUser()
SALT = settings.SECRET_KEY
try:
verified_payload = jwt.decode(
token,
SALT,
algorithms=['HS256'],
options={"require_exp": True}
)
username = verified_payload.get('username', '')
user = User.objects.filter(username=username).first()
except Exception as e:
user = AnonymousUser()
request.user = user
class Authentication(BaseAuthentication):
def authenticate(self, request):
try:
token = request.COOKIES['token']
except KeyError as e:
return AnonymousUser(), None
raise AuthenticationFailed({'code': 444, 'error': 'token 失效'})
except exceptions.ExpiredSignatureError:
return redirect('/login/')
raise AuthenticationFailed({'code': 444, 'error': 'token 失效'})
SALT = settings.SECRET_KEY
try:
verified_payload = jwt.decode(
token,
SALT,
algorithms=['HS256'],
options={"require_exp": True}
)
except exceptions.ExpiredSignatureError:
raise AuthenticationFailed({'code': 444, 'error': 'token 失效'})
except jwt.DecodeError:
raise AuthenticationFailed({'code': 445, 'error': 'token 认证失败'})
except jwt.InvalidTokenError:
raise AuthenticationFailed({'code': 446, 'error': '非法 token'})
return (verified_payload, token)
setting添加app
'tes_alert_admin.文件名.QtsAuthenticationMiddleware',
view中
from django.contrib.auth.mixins import LoginRequiredMixin
class IndexPage(LoginRequiredMixin, TemplateView):
pass
前端表单处理
表单处理,有时后端需要一些信息,可以通过hidden的form-group传递到后端
<form action="/url/" method="POST">
<div class="form-group">
<input type="hidden" name="xx" value="yy">
</div>
<div class="form-group">
xxx
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
分页
分页应该是有现成可用的库的
from django.core.paginator import Paginator
class xxxxxPage(LoginRequiredMixin, TemplateView):
def get(self, request, *args, **kwargs):
per_page = 15
page = int(request.GET.get('page',1))
rulelist = DataQuery(page, per_page) #数据库查询,返回一个list(list的元素是字典),将list写入pagination。
pagination = Paginator(rulelist, per_page)
page_obj = pagination.get_page(page)
return render(request,
'xx.html',
{
"pagination": pagination,
"page_obj": page_obj
}
)
前端对page_obj进行循环
分页部分
<div id="pages" class="text-center" >
<nav>
<ul class="pagination">
<li class="step-links">
<span class="current">
Page of </span>
</li></ul></nav>
</div>
前端多选multiselect
<link rel="stylesheet" href="/static/css/bootstrap-multiselect.css">
<script src="/static/js/bootstrap-multiselect.js"></script>
#多选项,通过xxlists的name传入后端,后端取值通过getlist,获取多选项的值
<div class="form-group">
<label for="selecttemplate" class="col-sm-2 control-label">xx项</label>
<div class="col-sm-10">
<select class="selectpicker" multiple data-style="btn-info" name="xxlists" data-live-search="true">
</select>
</div>
</div>
#checkbox 循环后端传来的list,作为checkbox的选项
#后端通过getlist获取多选的值
xxlist = request.POST.getlist('xxlists')
弹窗
弹窗按钮绑定一个 data-target,在对应的弹窗modal中,包含fade/dialog/content/header/body这些元素
<button type="button" class="btn" data-toggle="modal" data-target="#createButton">
按钮名
</button>
<!-- Modal 包含 弹窗fade/dialog/content/header/body-->
<div class="modal fade" id="createButton" tabindex="-1" role="dialog" aria-labelledby="createModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Title名</h4>
</div>
<div class="modal-body">
这里写弹窗的Body内容
</div>
<div class="modal-footer">
<button type="button" class="btn cancel btn-default" data-dismiss="modal">返回</button>
<button type="button" class="btn save btn-primary">保存</button>
</div>
</div>
</div>
</div>
<script>
$('.save.btn').on('click', function () {
$('.form').trigger('submit');
});
</script>
Models操作
1. M模型中XX字段包含yy信息的数据
M.objects.filter(XX__icontains='yy')
2. M模型多条件查询A字段或B字段包含yy的数据
from django.db.models import Q
M.objects.filter(Q(XX__icontains='yy') | Q(YY__icontains='yy'))
3. 范围查询
M.objects.filter(XX__gte='100')
4. 多数据查询
lista
M.objects.filter(XX__in=lista)
前端message
前端html添加(一般加到base中)
视图中
from django.contrib import messages
messages.warning(request, "警告信息")
messages.success(request, "成功信息")