01-07 user模块User表
一. 创建user模块
# 前提:在 luffy 虚拟环境下 # 1.终端从项目根目录进入apps目录 cd luffyapi & cd apps # 2.创建app python ../../manage.py startapp user
二. 创建User表对应的model:user/models.py
from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class UserInfo(AbstractUser): phone = models.CharField(max_length=11) # 需要pillow包的支持 icon = models.ImageField(upload_to='icon', default='icon/default.png') class Meta: verbose_name = '用户表' verbose_name_plural = verbose_name def __str__(self): return self.username
三. 注册user模块,配置User表:dev.py
INSTALLED_APPS = [ # ... 'user', ] # 自定义User表 AUTH_USER_MODEL = 'user.UserInfo'
四. 配置media
1. media配置:dev.py
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2. media目录(提示:不用配置,上传文件时会自动生成)
├── luffyapi └── luffyapi/ └── media/ └── icon └── default.png
3. 主路由:luffyapi/urls.py
from django.urls import path, include from django.views.static import serve from django.conf import settings import xadmin xadmin.autodiscover() # version模块自动注册需要版本控制的 Model from xadmin.plugins import xversion xversion.register_models() urlpatterns = [ # path('admin/', admin.site.urls), path('xadmin/', xadmin.site.urls), path('home/', include('home.urls')), path('user/', include('user.urls')), path('media/<path:path>/', serve, {'document_root': settings.MEDIA_ROOT}), ]
4. 数据库迁移
1)去向大luffyapi所在目录的终端 2)安装pillow模块 pip install pillow 3)数据库迁移(提示: 如果不去大luffyapi所在目录的终端是因为manage.py在那里) python manage.py makemigrations python manage.py migrate
五. 可能出现的错误及解决方法
1. django.db.migrations.exceptions.NodeNotFoundError:
# 执行python3.6 manage.py makemigrations时抛出异常 django.db.migrations.exceptions.NodeNotFoundError: Migration admin.0002_logentry_user dependencies reference nonexistent parent node ('app01', '0001_initial') django.db.migrations.exceptions。NodeNotFoundError:迁移管理。0002_logentry_user依赖项引用不存在的父节点('app01', '0001_initial') # 解决:在任意.py文件中导入以下, 删除以下中migrations中的除了__init__.py文件。 (提示:删除了也不要紧, 添加回来即可, 不然会抛出异常) from django.contrib.admin import migrations from django.contrib.auth import migrations
继承user的扩展表建好之后,在迁移,删除下图,在建扩展表,再迁移
2. 未在settings.py声明继承AbstractUser的表出现的异常
# models.py表继承了AbstractUser, 执行数据库迁移时出现异常 SystemCheckError: System check identified some issues: ERRORS: app01.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'. HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'. app01.User.phone: (fields.E120) CharFields must define a 'max_length' attribute. app01.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'. HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'. auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'. HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'. auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'. HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'. # 解决:配置文件中没有声明拓展的继承AbstractUser的表 AUTH_USER_MODEL = '应用名.表名'
3. Pillow模块未安装出现的异常
# 错误: ERRORS: auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'. HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'. auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'. HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'. user.User.avatar: (fields.E210) Cannot use ImageField because Pillow is not installed. HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "pip install Pillow". user.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'. HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'. user.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'. HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'. System check identified 5 issues (0 silenced). # 解决: 安装pillow模块 pip install pillow
01-08 luffy前台
一. 虚拟环境
# 1.傻瓜式安装node: 官网下载:https://nodejs.org/zh-cn/ # 2.安装cnpm, 以后使用淘宝提供的cnpm即可, 速度快。 ''' 查看看装是否成功版本: cnpm -v 可能出现的问题: 如果出现安装完毕以后提示‘不是内部或外部命令,也不是可运行的程序’ 解决: 第一步: 查看你看装完毕以后的路径是否添加到了环境变量, 没有添加则添加 C:\Users\qiao\AppData\Roaming\npm\cnpm 第二步: 重启你的命令终端 ''' npm install -g cnpm --registry=https://registry.npm.taobao.org # 3.安装vue最新脚手架 """ 查看安装是否成功, 输入vue出现提示: vue """ cnpm install -g @vue/cli # 注:如果2、3步报错,清除缓存后重新走2、3步 npm cache clean --force
输入vue出现提示: vue
二. 创建项目
1. 在命令行中输入命令创建项目
# 前提:在目标目录新建luffy文件夹 cd 建立的luffy文件夹 vue create luffycity # luffycity是项目名
2. 命令行创建项目流程
第一步: 选择手动选择功能 -》 Manually select features
Vue CLI v4.4.6 ? Please pick a preset: default (babel, eslint) # 默认 > Manually select features # 手动选择功能(回车)
第二步:
# 提示: 空格选中, 回车确认 Vue CLI v4.4.6 ? Please pick a preset: Manually select features ? Check the features needed for your project: (*) Babel # 默认选中 ( ) TypeScript ( ) Progressive Web App (PWA) Support >(*) Router # 路由 (*) Vuex # 状态管理器 ( ) CSS Pre-processors ( ) Linter / Formatter ( ) Unit Testing ( ) E2E Testing
第三步:
Vue CLI v4.4.6 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, Router, Vuex ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Where do you prefer placing config for Babel, ESLint, etc.? # ESLint, Babel存放的位置。 存放在 In package.json中一般 In dedicated config files > In package.json
第四步:
? Save this as a preset for future projects? (y/N) y # 将此保存为将来项目的预置(都行)
完成配置:
3. 使用vue/cli启动服务,使用图形化界面创建vue项目
# 终端下输入命令: vue ui # 关闭 ctrl+c
三. 目录介绍及开拓项目目录
├── luffycity ├── public/ # 项目共有资源 ├── favicon.ico # 站点图标 └── index.html # 主页 ├── src/ # 项目主应用,开发时的代码保存 ├── assets/ # 前台静态资源总目录 ├── css/ # 自定义css样式 └── global.css # 自定义全局样式 ├── js/ # 自定义js样式 └── settings.js # 自定义配置文件 └── img/ # 前台图片资源 ├── components/ # 小组件目录 ├── views/ # 页面组件目录 ├── App.vue # 入口脚本文件 ├── router └── index.js # 路由脚本文件 store └── index.js # 仓库脚本文件 ├── vue.config.js # 项目配置文件 └── *.* # 其他配置文件
1. 文件修订:目录中非配置文件的多余文件可以删除
1) 应用程序
<template> <div id="app"> <router-view/> </div> </template>
2) 路由器/ index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter); const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/home', redirect: '/', }, ]; const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
3) 主场
<template> <div class="home"> </div> </template> <script> export default { name: 'home', components: { }, } </script>
四. 全局配置:变量样式,配置文件
1. 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. settings.js
export default { base_url: 'http://127.0.0.1:8000' }
3. main.js
// 配置全局样式 import '@/assets/css/global.css' // 配置全局自定义设置 import settings from '@/assets/js/settings' Vue.prototype.$settings = settings; // 在所有需要与后台交互的组件中:this.$settings.base_url + '再拼接具体后台路由'
五. 启动项目相关配置
1. 编辑配置中配置按钮
2. 命令行输入
npm run serve
六. 拓展
1. node_modules文件夹被删除或者出问题解决方法
npm install
01-09 luffy前台配置
一. axios前后台交互
1. 安装:前端项目目录下的终端
cnpm install axios
2. 配置:main.js
import axios from 'axios' Vue.prototype.$axios = axios;
二. cookies操作
1. 安装:前端项目目录下的终端
cnpm install vue-cookies
2. 配置:main.js
import cookies from 'vue-cookies' Vue.prototype.$cookies = cookies;
三. element-ui页面组件框架
1. 安装:前端项目目录下的终端
cnpm install element-ui
2. 配置:main.js
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
四. bootstrap页面组件框架
1. 安装:前端项目目录下的终端
cnpm install jquery cnpm install bootstrap@3
2. 配置jquery:vue.config.js
const webpack = require("webpack"); module.exports = { configureWebpack: { plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", "window.$": "jquery", Popper: ["popper.js", "default"] }) ] } };
3. 配置bootstrap:main.js
import 'bootstrap' import 'bootstrap/dist/css/bootstrap.min.css'
main.js
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false // 配置全局样式,@符合代指src路径 import '@/assets/css/global.css' // 配置全局自定义设置 import settings from '@/assets/js/settings' Vue.prototype.$settings = settings; // 在所有需要与后台交互的组件中:this.$settings.base_url + '再拼接具体后台路由' // axios配置 import axios from 'axios' // 导入安装的axios // 相当于把axios这个对象放到了vue对象中,以后用 vue对象.$axios Vue.prototype.$axios = axios; // cookies配置 import cookies from 'vue-cookies' Vue.prototype.$cookies = cookies; // ElementUI配置 import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); // bootstrap配置 import 'bootstrap' import 'bootstrap/dist/css/bootstrap.min.css' new Vue({ router, store, render: h => h(App) }).$mount('#app')
01-10 luffy前台主页
一. 图片准备
将提供的资料中的图片移植到项目的img文件夹下
前后台打通
// 组件在创建的时候,就向后端发送请求 // this就是vue对象 this.$axios.get('http://127.0.0.1:8000/home/home/').then(function (response) { console.log(response) }).catch(function (error) { console.log(error) }) // es6的箭头函数 function (response) {console.log(response)} response=>{console.log(response)}
路飞项目头部组件
# html中路由跳转 <router-link to="/"> <img src="../assets/img/head-logo.svg" alt=""> </router-link> # js中控制路由跳转 this.$router.push(url_path)
二. 页头组件:components / Header.vue
<template> <div class="header"> <div class="slogan"> <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</p> </div> <div class="nav"> <ul class="left-part"> <li class="logo"> <router-link to="/"> <img src="../assets/img/head-logo.svg" alt=""> </router-link> </li> <li class="ele"> <span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">免费课</span> </li> <li class="ele"> <span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">实战课</span> </li> <li class="ele"> <span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">轻课</span> </li> </ul> <div class="right-part"> <div> <span>登录</span> <span class="line">|</span> <span>注册</span> </div> </div> </div> </div> </template> <script> export default { name: "Header", data() { return { url_path: sessionStorage.url_path || '/', } }, methods: { goPage(url_path) { // 已经是当前路由就没有必要重新跳转 if (this.url_path !== url_path) { this.$router.push(url_path); } sessionStorage.url_path = url_path; }, }, created() { sessionStorage.url_path = this.$route.path; this.url_path = this.$route.path; } } </script> <style scoped> .header { background-color: white; box-shadow: 0 0 5px 0 #aaa; } .header:after { content: ""; display: block; clear: both; } .slogan { background-color: #eee; height: 40px; } .slogan p { width: 1200px; margin: 0 auto; color: #aaa; font-size: 13px; line-height: 40px; } .nav { background-color: white; user-select: none; width: 1200px; margin: 0 auto; } .nav ul { padding: 15px 0; float: left; } .nav ul:after { clear: both; content: ''; display: block; } .nav ul li { float: left; } .logo { margin-right: 20px; } .ele { margin: 0 20px; } .ele span { display: block; font: 15px/36px '微软雅黑'; border-bottom: 2px solid transparent; cursor: pointer; } .ele span:hover { border-bottom-color: orange; } .ele span.active { color: orange; border-bottom-color: orange; } .right-part { float: right; } .right-part .line { margin: 0 10px; } .right-part span { line-height: 68px; cursor: pointer; } </style>
三. 轮播图组件:components / Banner.vue
<template> <div class="banner"> <el-carousel height="400px"> <el-carousel-item v-for="item in 4" :key="item"> <img src="../assets/img/banner1.png" alt=""> </el-carousel-item> </el-carousel> </div> </template> <script> export default { name: "Banner" } </script> <style scoped> .el-carousel__item { height: 400px; min-width: 1200px; } .el-carousel__item img { height: 400px; margin-left: calc(50% - 1920px / 2); } </style>
四. 页脚组件:components / Footer.vue
<template> <div class="footer"> <ul> <li>关于我们</li> <li>联系我们</li> <li>商务合作</li> <li>帮助中心</li> <li>意见反馈</li> <li>新手指南</li> </ul> <p>Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p> </div> </template> <script> export default { name: "Footer" } </script> <style scoped> .footer { width: 100%; height: 128px; background: #25292e; color: #fff; } .footer ul { margin: 0 auto 16px; padding-top: 38px; width: 810px; } .footer ul li { float: left; width: 112px; margin: 0 10px; text-align: center; font-size: 14px; } .footer ul::after { content: ""; display: block; clear: both; } .footer p { text-align: center; font-size: 12px; } </style>
五. 家庭组件:views / Home.vue
<template> <div class="home"> <Header /> <Banner /> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <Footer /> </div> </template> <script> import Header from '../components/Header' import Footer from '../components/Footer' import Banner from '../components/Banner' export default { name: "Home", components: { Header, Footer, Banner, } } </script>
六 路由
router.js
import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue' import ActualCourse from '../views/ActualCourse.vue' import FreeCourse from '../views/FreeCourse.vue' import LightCourse from '../views/LightCourse.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/free-course', name: 'FreeCourse', component: FreeCourse },{ path: '/actual-course', name: 'ActualCourse', component: ActualCourse },{ path: '/light-course', name: 'LightCourse', component: LightCourse }, ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
01-11 后台主页模块设计
一. 创建home模块
# 前提:在 luffy 虚拟环境下 # 1.终端从项目根目录进入apps目录 cd luffyapi & cd apps # 2.创建app python ../../manage.py startapp home
二. 路由分发
子路由:home/urls.py
from django.urls import path, include from rest_framework.routers import SimpleRouter from . import views router = SimpleRouter() router.register('banner', views.BannerViewSet, 'banner') urlpatterns = [ path('', include(router.urls)), ]
三. Banner数据表model设计
1. utils/model.py 基表
from django.db import models # Create your models here. class BaseModel(models.Model): create_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
2. home/models.py
from django.db import models from luffyapi.utils.models import BaseModel class Banner(BaseModel): title = models.CharField(max_length=32, verbose_name='图片名字') img = models.ImageField(upload_to='banner', null=True, verbose_name='轮播图', help_text='图片尺寸必须是:3840*800') link = models.CharField(max_length=32, verbose_name='跳转链接') info = models.TextField(verbose_name='图片简介') class Meta: verbose_name_plural = '轮播图表' def __str__(self): return self.title
3. 数据迁移:在大luffyapi路径下的终端
python manage.py makemigrations python manage.py migrate
三. 注册home模块:dev.py
INSTALLED_APPS = [ 'rest_framework', 'home', ]
四. 设计Banner数据接口
1. home/serializers.py
from rest_framework import serializers from . import models class BannerModelSerializer(serializers.ModelSerializer): class Meta: model = models.Banner fields = ['title', 'img', 'link']
2. home/views.py
from rest_framework.viewsets import ModelViewSet from rest_framework import mixins from . import models, serializers class BannerViewSet(ModelViewSet, mixins.ListModelMixin): queryset = models.Banner.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.BannerSerializer
4. 接口
http://localhost:8000/home/banners/python
01-12 跨域请求详解
一. 同源策略
1. 什么是同源策略?
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现 # 同源策略判断的依据: 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同. 比如: 我在本地上的域名是127.0.0.1:8000,请求另外一个域名:127.0.0.1:8001一段数据
浏览器上就会报错,这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险
已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截
二. CORS(跨域资源共享)简介
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
三. CORS基本流程
# 浏览器将CORS请求分成两类: 简单请求(simple request)和 非简单请求(not-so-simple request)。 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。 浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。
只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
四. CORS两种请求详解
只要同时满足以下两大条件,就属于简单请求。
# 1. 请求方法是以下三种方法之一: HEAD GET POST # 2. HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
# 简单请求和非简单请求的区别? 简单请求: 一次请求 非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。 # 关于“预检” 请求方式:OPTIONS “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息 # 如何“预检” 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过 Access-Control-Allow-Methods 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过 Access-Control-Allow-Headers
支持跨域,简单请求
服务器设置响应头:Access-Control-Allow-Origin = ‘域名’ 或 ‘*’
支持跨域,复杂请求
由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。 “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Allow-Methods “预检”请求时,允许请求头则需服务器设置响应头: Access-Control-Allow-Headers
如果发送post请求,数据格式是json---->非简单请求,非简单请求发两次,一次OPTTIONS请求,一次真正的请求
五. Django项目中支持CORS
在返回的结果中加入允许信息(简单请求)
def test(request): import json obj = HttpResponse(json.dumps({'name': 'lqz'})) # obj['Access-Control-Allow-Origin'] =' *' obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8004' return obj
放到中间件处理复杂和简单请求:
from django.utils.deprecation import MiddlewareMixin class CorsMiddleWare(MiddlewareMixin): def process_response(self, request, response): if request.method == "OPTIONS": # 可以加* response["Access-Control-Allow-Headers"] = "Content-Type" response["Access-Control-Allow-Origin"] = "http://localhost:8080" return response
六. django 使用django-cors-headers 解决跨域问题
1、使用pip安装
pip install django-cors-headers
2、添加到setting的app中
INSTALLED_APPS = ( ... 'corsheaders', ... )
3、添加中间件
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10 'corsheaders.middleware.CorsMiddleware', ]
4、setting下面添加下面的配置
完整配置:
CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_WHITELIST = ( '*' ) CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW', ) CORS_ALLOW_HEADERS = ( 'XMLHttpRequest', 'X_FILENAME', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', 'Pragma', )
一般配置:
CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW', ) CORS_ALLOW_HEADERS = ( 'authorization', 'content-type', )
5. 抛出异常: ERRORS:
?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc HINT: Add a scheme (e.g. https://) or netloc (e.g. example.com).
# 注释掉这行代码, 因为这是添加白名单用户 CORS_ORIGIN_WHITELIST = ( '*' )
01-13 Xadmin的使用
一. 介绍
xadmin是Django的第三方扩展,可是使Django的admin站点使用更方便。
文档:https://xadmin.readthedocs.io/en/latest/index.html
二. 安装
通过如下命令安装xadmin的跟django2.2.2匹配
pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 --default-timeout=1000
下载后,会自动更新django,需要下载底版本的xadmin配套 模块
requirements.txt
certifi==2022.9.24 charset-normalizer==2.1.1 diff-match-patch==20200713 django-crispy-forms==1.9.1 django-formtools==2.1 django-import-export==0.5.1 django-reversion==2.0.0 future==0.15.2 httplib2==0.9.2 idna==3.4 pytz==2022.4 requests==2.28.1 setuptools==65.3.0 six==1.10.0 sqlparse==0.4.3 tablib==3.2.1 urllib3==1.26.12 wheel==0.37.1
执行pip install -r requirements.txt
对照报错信息进行修改:
把from django.core.urlresolvers import NoReverseMatch, reverse 修改为:
from django.urls import NoReverseMatch, reverse
在配置文件中注册如下应用
INSTALLED_APPS = [ ... # xadmin主体部分 'xadmin', # 渲染表格模块 'crispy_forms', # 为模型通过版本控制,可以回滚数据 'reversion', ... ]
xadmin有建立自己的数据库模型类,需要进行数据库迁移
# 其实makemigrations已经帮我们做好了, 只需要migrate就行了 # 查看 from xadmin import migrations # 执行以下命令 python manage.py makemigrations python manage.py migrate
在总路由中添加xadmin的路由信息
import xadmin xadmin.autodiscover() # version模块自动注册需要版本控制的 Model from xadmin.plugins import xversion xversion.register_models() urlpatterns = [ path(r'xadmin/', xadmin.site.urls) ]
创建超级用户
python manage.py createsuperuser
三. 使用
-
xadmin不再使用Django的admin.py,而是需要编写代码在adminx.py文件中。
-
xadmin的站点管理类不用继承
admin.ModelAdmin
,而是直接继承object
即可。
例如:在子应用中创建adminx.py文件。
1. 站点的全局配置
user应用下的adminx.py
import xadmin from xadmin import views class BaseSetting(object): """xadmin的基本配置""" enable_themes = True # 开启主题切换功能 use_bootswatch = True xadmin.site.register(views.BaseAdminView, BaseSetting) class GlobalSettings(object): """xadmin的全局配置""" site_title = "路飞学城" # 设置站点标题 site_footer = "路飞学城有限公司" # 设置站点的页脚 menu_style = "accordion" # 设置菜单折叠 xadmin.site.register(views.CommAdminView, GlobalSettings)
2. 站点Model管理
xadmin可以使用的页面样式控制基本与Django原生的admin一直。
list_display 控制列表展示的字段
list_display = ['id', 'btitle', 'bread', 'bcomment']
search_fields 控制可以通过搜索框搜索的字段名称,xadmin使用的是模糊查询
search_fields = ['id','btitle']
list_filter 可以进行过滤操作的列,对于分类、性别、状态
list_filter = ['is_delete']
-
ordering 默认排序的字段
-
readonly_fields 在编辑页面的只读字段
-
exclude 在编辑页面隐藏的字段
-
list_editable 在列表页可以快速直接编辑的字段
-
show_detail_fields 在列表页提供快速显示详情信息
-
refresh_times 指定列表页的定时刷新
refresh_times = [5, 10,30,60] # 设置允许后端管理人员按多长时间(秒)刷新页面
list_export 控制列表页导出数据的可选格式
list_export = ('xls', 'xml', 'json') list_export设置为None来禁用数据导出功能 list_export_fields = ('id', 'btitle', 'bpub_date')
show_bookmarks 控制是否显示书签功能
show_bookmarks = True
data_charts 控制显示图表的样式
data_charts = { "order_amount": { 'title': '图书发布日期表', "x-field": "bpub_date", "y-field": ('btitle',), "order": ('id',) }, # 支持生成多个不同的图表 # "order_amount": { # 'title': '图书发布日期表', # "x-field": "bpub_date", # "y-field": ('btitle',), # "order": ('id',) # }, }
-
title 控制图标名称
-
x-field 控制x轴字段
-
y-field 控制y轴字段,可以是多个值
-
order 控制默认排序
model_icon 控制菜单的图标
class BookInfoAdmin(object): model_icon = 'fa fa-gift' xadmin.site.register(models.BookInfo, BookInfodmin)
标签:vue,name,项目,基础,xadmin,user,import,User From: https://www.cnblogs.com/coderxueshan/p/17779538.html