二次封装Response模块
# drf提供的Response,前端想接收到的格式 {code:xx,msg:xx}
后端返回,前端收到:APIResponse(tokne='asdfa.asdfas.asdf')---->{code:100,msg:成功,token:asdfa.asdfas.asdf} APIResponse(code=101,msg='用户不存在') ---->{code:101,msg:用户不存在} APIResponse(results=[{},{}])---->{code:100,msg:成功,results:[{},{}]} APIResponse(msg='创建成功')---->{code:100,msg:创建成功} APIResponse(token=sd.11.22,icon='用户头像')---->{code:100,msg:创建成功,token:sd.11.22,icon:'用户头像'} APIResponse(msg='创建成功',headers={'xx':xxx})---->{code:100,msg:创建成功}
# 开始封装:
# utills/common_response.py from rest_framework.response import Response class APIResponse(Response): def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs): data = {'code': code, 'msg': msg} if kwargs: # kwargs={token:xx,icon:zz} data.update(kwargs) # super().__init__()---等同于 -->Response(data=data) super().__init__(data=data, headers=headers, status=status)
# views.py from utils.common_response import APIResponse class TestResponseView(APIView): def get(self, request): # retur n APIResponse(token='ss.ee.ss',icon='/media/icon/default.png') # return APIResponse(msg='创建成功') # return APIResponse(msg='用户不存在',code=101) # return APIResponse(results=[{},{}]) return APIResponse(headers={'xx': 'yy'}) # raise APIException(detail='用户名或密码错误') # {code:999,msg:用户名或密码错误}
admin和国际化问题
# admin 注释掉,重新启动
* url中注册app
* 重新迁移
# 国际化LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
5个视图扩展类封装
# utills/mixins.py from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, \ RetrieveModelMixin from .common_response import APIResponse class CommonListModelMixin(ListModelMixin): def list(self, request, *args, **kwargs): # Response 的对象---》res.data res = super().list(request, *args, **kwargs) return APIResponse(results=res.data) # {code:100,msg:成功,results:[{},{},{}]} class CommonCreateModelMixin(CreateModelMixin): def create(self, request, *args, **kwargs): res = super().create(request, *args, **kwargs) return APIResponse(msg='新增成功', result=res.data) # {code:100,msg:新增成功,result:{}} class CommonDestroyModelMixin(DestroyModelMixin): def destroy(self, request, *args, **kwargs): super().destroy(request, *args, **kwargs) return APIResponse(msg='删除成功') # {code:100,msg:删除成功} class CommonUpdateModelMixin(UpdateModelMixin): def update(self, request, *args, **kwargs): super().update(request, *args, **kwargs) return APIResponse(msg='修改成功') # {code:100,msg:修改成功} class CommonRetrieveModelMixin(RetrieveModelMixin): def retrieve(self, request, *args, **kwargs): res = super().retrieve(request, *args, **kwargs) return APIResponse(result=res.data) # {code:100,msg:成功,result:{}}
开启media访问
# 上传文件( ImageField,FileField ),会自动传到 media文件夹下的 to 的路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = 'media/'
# 在总路由中配置:
from django.conf import settings from django.views.static import serve path('media/<path:path>', serve, kwargs={'document_root': settings.MEDIA_ROOT}), # http://127.0.0.1:8000/media/icon/2.png
前端创建--vue2
前端使用vue2搭建,使用pycharm打开运行,删除不需要的样式和vue文件
vue create luffy_city
前端配置
1、全局样式:
# 在main.js里引入:
//在这里导入即可--全局样式生效 import '@/assets/css/global.css'
/* assets/css/global.css */ /* 声明全局样式和项目的初始化样式 */ body, h1, h2, h3, h4, h5, h6, p, table, tr, td, ul, li, a, form, input, select, option, textarea { margin: 0; padding: 0; font-size: 15px; } a { text-decoration: none; color: #333; } ul { list-style: none; } table { border-collapse: collapse; /* 合并边框 */ }
2、配置文件(路由):
# 在main.js中注册
以后再任意组件中,this.$settings.BASE_URL # 拿到基地址
// main.js import settings from "@/assets/js/settings"; Vue.prototype.$settings = settings /* asesst/ js/ settings.jss */ export default { BASE_URL: 'http://127.0.0.1:8000/api/v1/' }
3、axios:
# 安装:cnpm install -S axios
// main.js import axios from "axios"; Vue.prototype.$axios = axios // 以后再任意组件中直接使用 this.$axios.get(this.$settings.BASE_URL+'user/user/loign/')
4、使用elementui:
# 安装: cnpm install element-ui -S
# 网址:组件 | Element
// main.js import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
5、操作cookie:
# 安装:cnpm install vue-cookies
# 以后任意组件直接使用:this.$cookies.set / this.$cookies.get
// main.js import cookies from 'vue-cookies' Vue.prototype.$cookies = cookies;
6、使用bootstrap:
# 安装:cnpm install bootstrap@5卸载:cnpm remove bootstrap@4
# 在组件中使用: <button class="btn btn-danger">点我看美女</button>
// main.js import 'bootstrap/dist/css/bootstrap.min.css'
后端之轮播图
首页home---轮播图接口
轮播图表:#utils / common_model.py from django.db import models class BaseModel(models.Model): created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') updated_time = models.DateTimeField(auto_now=True, verbose_name='最后更新时间') is_delete = models.BooleanField(default=False, verbose_name='是否删除') is_show = models.BooleanField(default=True, verbose_name='是否上架') orders = models.IntegerField(verbose_name='优先级') class Meta: abstract = True # 这样写了,这张表是个虚拟的,不会在数据库创建,只用来继承
# home/models 继承common_models.py from utills.common_model import BaseModel # 通过写一个BaseModel 实现,以后如果其他表中有对应字段,直接继承即可 class Banner(BaseModel): title = models.CharField(max_length=16, unique=True, verbose_name='名称') image = models.ImageField(upload_to='banner', verbose_name='图片') link = models.CharField(max_length=64, verbose_name='跳转链接') info = models.TextField(verbose_name='详情')
轮播图接口:这里运用了自定义配置common_settings,参考下列知识
# home/serializers.py from rest_framework import serializers from .models import Banner class BannerSerializer(serializers.ModelSerializer): class Meta: model = Banner fields = ['id', 'title', 'image', 'link']
# home/views.py from .models import Banner from rest_framework.viewsets import GenericViewSet from utills.mixins import CommonListModelMixin from .serializers import BannerSerializer from django.conf import settings # 查询所有轮播图 class BannerView(GenericViewSet, CommonListModelMixin): # qs对象可以切片----》 limit 2 queryset = Banner.objects.all().filter(is_delete=False, is_show=True).order_by('orders')[:settings.BANNER_COUNT] serializer_class = BannerSerializer
# urls.py from django.urls import path,include urlpatterns = [ path('api/v1/home/', include('home.urls')), ] # home/urls.py from rest_framework.routers import SimpleRouter from .views import BannerView router=SimpleRouter() router.register('banner',BannerView,'banner') urlpatterns = [ ] urlpatterns += router.urls
自定义配置
1、以后咱们会有自定义的配置 common_settings.py
# settings/common_settings # 自定义配置 BANNER_COUNT=3 # 还有自己其他的配置,都写在这里
2、将自定义配置引入总 settings/dev.py 中
# 导入common_settings.py from .common_settings import *
3、只需要在配置文件中导入:from .common_settings import *
前后端打通
1、
2、
3、
跨域问题详解
1、
2、
3、