from django.contrib.ContentTypes.fIElds import GenericRelationclass Course(models.Model): name = models.CharFIEld(verbose_name="课程名",max_length=32) Title = models.CharFIEld(verbose_name="课程简介",max_length=128,null=True,blank=True) # 存放media文件夹下图片的相对路径:eg: media/python入门.jpeg image = models.CharFIEld(verbose_name="海报",max_length=64,blank=True) # 用户连表查询,不会在数据库中产生字段 price_policy = GenericRelation(to=‘PricePolicy‘) def __str__(self): return self.name class Meta: verbose_name_plural = "免费课程"class CourseDetail(models.Model): level = models.IntegerFIEld(default=1,choices=((0,‘初级‘),(1,"中级"),(2,"高级"))) movIE_url = models.CharFIEld(max_length=64) info = models.TextFIEld() course = models.OnetoOneFIEld(to=‘Course‘,on_delete=models.SET_NulL,db_constraint=False) teacher = models.OnetoOneFIEld(to=‘Teacher‘,db_constraint=False) def __str__(self): return self.course.name + ‘的详情‘ class Meta: verbose_name_plural = "免费课程详情"class Teacher(models.Model): name = models.CharFIEld(max_length=32) info = models.TextFIEld() image = models.CharFIEld(max_length=64) level = models.IntegerFIEld(default=0,‘初级讲师‘),"金牌讲师"),"特约讲师"))) def __str__(self): return self.name class Meta: verbose_name_plural = "讲师"class DegreeCourse(models.Model): name = models.CharFIEld(max_length=32) price_policy = GenericRelation(to=‘PricePolicy‘) def __str__(self): return self.name class Meta: verbose_name_plural = "学位课程"from django.contrib.ContentTypes.models import ContentTypefrom django.contrib.ContentTypes.fIElds import GenericForeignKeyclass PricePolicy(models.Model): day = models.IntegerFIEld() price = models.CharFIEld(max_length=8) object_ID = models.IntegerFIEld() content_type = models.ForeignKey(to=ContentType,null=True) # 改 *** 作只用于ContentType连表查询,不会产生表字段,就是关联课程表的对象 model_obj = GenericForeignKey() def __str__(self): return "%s:(%s天 ¥:%s)" % (self.model_obj.name,self.day,self.price) class Meta: verbose_name_plural = "价格策略"前台路由与页面 APP.vue组件
<div ID="nav"> <router-link to="/">主页</router-link> | <router-link to="/login">登录</router-link> | <router-link to="/course">免费课程</router-link> | <!-- 在页面中转跳路由传递参数,传递了params参数,this.$router.params可以拿到这个参数字典 --> <!--<router-link :to="{‘name‘: ‘degree-course‘,‘params‘: {‘ID‘: 1,‘name‘: ‘owen‘}}">学位课程</router-link>--> <router-link :to="{‘name‘: ‘degree-course‘}">学位课程</router-link></div>router.Js路由配置
# 在vIEws文件夹中建立对应的组件{ path: ‘/login‘,name: ‘login‘,component: () => import(‘./vIEws/Login.vue‘)},{ path: ‘/course‘,name: ‘course‘,component: () => import(‘./vIEws/Course.vue‘)},{ path: ‘/degree-course‘,name: ‘degree-course‘,component: () => import(‘./vIEws/DegreeCourse.vue‘)},{ path: ‘/course-detail‘,name: ‘course-detail‘,component: () => import(‘./vIEws/CourseDetail.vue‘)}项目开发视图与响应的二次封装 响应
# API.utils.pyclass APIResponse: def __init__(self,status=0,message=‘ok‘): self.status = status self.message = message # 要返回给前台的API字典 @property def API_dic(self): return self.__dict__视图
# 在API应用文件夹下创建包vIEws# 1.分文件管理不同的视图类,视图类继承ModelVIEwSet管理一系列视图函数# 2.在__ini__文件中统一管理到 视图类# __init__.pyfrom .Course import CourseVIEw# vIEws文件夹/Course文件/CourseVIEwfrom rest_framework.vIEwsets import ModelVIEwSetfrom rest_framework.response import Responsefrom API.utils import APIResponsefrom API import models,objectJsonclass CourseVIEw(ModelVIEwSet): def get(self,request,*args,**kwargs): API_response = APIResponse() course_List = models.Course.objects.all() course_data = objectJson.CourseJson(course_List,many=True).data API_response.results = course_data return Response(API_response.API_dic)免费课程首页展示 main.Js配置后台请求根路径
// 后台根接口Vue.prototype.$base_API = ‘http://127.0.0.1:8000/‘;vIEws/Course.vue
<template> <div class="course"> <h2>免费课程</h2> <!--course_List是从后台获取,有多少条数据,就会渲染多少个子组件CourseVIEw--> <div v-for="(course,i) in course_List" :key="course.name+i"> <!--通过绑定属性的方式,将course传给属性course,在组件内部提高props=[‘course‘]拿到父组件的数据--> <CourseVIEw :course="course"></CourseVIEw> </div> </div></template><script> import CourseVIEw from "../components/CourseVIEw"; export default { name: "Course",data: function () { return { course_List: [] } },components: { CourseVIEw: CourseVIEw,},mounted: function () { let _this = this; this.$AJAX({ method: ‘get‘,url: this.$base_API + ‘courses/‘,}).then(function (response) { _this.course_List = response.data.results }) } }</script><style scoped></style>components/CourseVIEw.vue
<template> <div class="course-vIEw"> <div class="Box"> <h3 @click="goDetail(course.ID)">{{course.name }}</h3> <p>{{ course.Title }}</p> </div> <img @click="goDetail(course.ID)" :src="$base_API + course.image" alt=""> </div></template><script> export default { name: "CourseVIEw",props: [‘course‘],methods: { goDetail: function (pk) { //前往详情页,在方法中,router如何完成路由的跳转 this.$router.push(‘/course-detail‘); // 业务逻辑下,路由转跳携带参数 this.$router.course_ID = pk; window.console.log(pk) } } }</script><style scoped> .course-vIEw { padding: 0 200px; margin: 25px 0; } .course-vIEw .Box { @R_404_5987@: left; wIDth: 380px; } .course-vIEw img { wIDth: 400px; @R_404_5987@: left; } .course-vIEw:after { display: block; clear: both; content: ‘‘; }</style>vIEws/Course.vue/CourseDetail.vue
<template> <div class="course-detail"> <h2>免费课程详情</h2> <p>{{ detail }}</p> </div></template><script> export default { name: "CourseDetail",data: function () { return { detail: {},} },url: this.$base_API + ‘course/‘ + this.$router.course_ID + ‘/‘,}).then(function (response) { window.console.log(response); _this.detail = response.data.results; }) } }</script><style scoped></style>前后台登录认证 时区国际化settings.py
TIME_ZONE = ‘Asia/Shanghai‘USE_TZ = Falsemodels.py
class User(models.Model): username = models.CharFIEld(max_length=32) password = models.CharFIEld(max_length=32)class UserToken(models.Model): token = models.CharFIEld(max_length=64) user = models.OnetoOneFIEld(to=‘User‘,db_constraint=False) update_time = models.DateTimeFIEld(auto_Now=True) Failed_time = models.@R_404_5987@FIEld(default=10)objectson.py
class Userjson(serializers.ModelSerializer): class Meta: model = models.User fIElds = ‘__all__‘class UserTokenjson(serializers.ModelSerializer): class Meta: model = models.UserToken fIElds = ‘__all__‘auth.py
from rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import AuthenticationFailedfrom API import modelsclass LoginAuthenticate(BaseAuthentication): def authenticate(self,request): token = request.Meta.get(‘http_TOKEN‘) result = models.UserToken.objects.filter(token=token).first() # type:models.UserToken if result: # 最近一次登录的时间 before_time = result.update_time # 过期时长秒数 Failed_time = result.Failed_time # 当你时间往前推演到过期的时长前的最后时刻 import datetime time_difference = datetime.datetime.Now() - datetime.timedelta(seconds=Failed_time) import time # 存在时区问题,通过国际化解决 before_time_stamp = time.mktime(before_time.timetuple()) # 拿到时间戳 time_difference_stamp = time.mktime(time_difference.timetuple()) if before_time_stamp >= time_difference_stamp: return result.user,token raise AuthenticationFailed(‘登录过期‘) else: raise AuthenticationFailed(‘认证失败‘)前台安装 *** 作cookie的模块
<template> <div class="login"> <h2>登录页面</h2> <div class="form"> <el-form :model="form" label-wIDth="100px"> <el-form-item label="用户名"> <el-input v-model="form.username"></el-input> </el-form-item> <el-form-item label="密码"> <el-input type="password" v-model="form.password" autocomplete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onsubmit">登录</el-button> </el-form-item> </el-form> </div> </div></template><script> export default { name: "Login",data: function () { return { form: { username: ‘‘,password: ‘‘,} } },methods: { onsubmit() { // window.console.log(‘aaaa‘); let _this = this; this.$AJAX({ method: ‘post‘,url: this.$base_API + ‘login/‘,data: { username: this.form.username,password: this.form.password } }).then(function (response) { window.console.log(response); let token = response.data.token; _this.$cookie.set(‘token‘,token); _this.$router.push(‘/‘) }) } } }</script><style scoped></style>VIEw Code router.Js
{ path: ‘/login‘,component: () => import(‘./vIEws/Login.vue‘) },总结
以上是内存溢出为你收集整理的登录、认证、token处理、前台cookie存储token全部内容,希望文章能够帮你解决登录、认证、token处理、前台cookie存储token所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)