首页 > 其他分享 >项目基础(二)

项目基础(二)

时间:2023-10-21 21:01:15浏览次数:38  
标签:vue name 项目 基础 xadmin user import User

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',)
    #    },
    }
  1. title 控制图标名称

  2. x-field 控制x轴字段

  3. y-field 控制y轴字段,可以是多个值

  4. 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

相关文章

  • PMP项目生命周期的区分
     预测型迭代型增量型敏捷型需求在开发前预先确定需求在交付期间定期细化需求在交付期间频繁细化针对最终可交付成果制定交付计划,然后在项目终了时一次交付最终产品分次交付整体产品的各种子集频繁交付对客户有价值的各种子集(隶属于整体产品)尽量限制......
  • Java基础 File 常见的成员方法(创建、删除)
     createNewFile() 方法:细节一:如果当前路径表示的文件不存在,则创建成功,方法返回true;如果当前路径表示的文件已经存在,则创建失败,方法返回false细节二:如果父级路径是不存在的,那么方法会有IOException异常细节三:createNewFile() 方法创建的一定是文件。如果路径当中不......
  • 实验2 C语言分支与循环基础应用编程
    实验任务1源代码1#include<stdio.h>2#include<stdlib.h>3#include<time.h>45#defineN56#defineN13747#defineN246589intmain()10{11intnumber;12inti;1314srand(time(0));1516......
  • Java基础 File 常见的成员方法(判断、获取)
     length()方法的细节:只能获取文件的大小,单位是字节。如果我们想要的单位是M,G等,可以不断地除以1024       len/1024:KB  len/1024/1024:MB  len/1024/1024/1024:G如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在......
  • 探索数据库的世界:从基础到高级
    数据库是现代计算机科学中不可或缺的重要组成部分。无论是在商业领域中管理海量数据,还是在科学研究中处理复杂的实验数据,数据库都扮演着关键的角色。本篇博文将带你深入探索数据库的世界,从基础知识到高级应用,帮助你更好地理解和应用数据库技术。第一部分:数据库基础在介绍数据库的......
  • Java基础 File
    File对象就表示一个路径,可以是文件的路径,也可以是文件夹的路径。甚至这个路径可以是存在的,也可以是不存在的 File类常见的构造方法有三个:public File(String pathname)  →  根据文件路径创建文件对象。把字符串表示的路径变成File对象public File(String......
  • web基础漏洞-越权漏洞
    1、介绍越权,是指攻击者访问或者操作了超过当前身份权限的资源。2、场景(1)水平越权攻击者登录账号,对其它账号的专属数据进行了请求或操作。(2)垂直越权1攻击者未登录,而直接对账号专属数据进行了请求或操作。(3)垂直越权2攻击者登录,但是对需要更高权限的数据进行了请求或操......
  • web基础漏洞-验证码爆破
    1、介绍验证码爆破,攻击者可以持续请求验证,从而获取正确验证码。2、防护(1)限制验证码有效时间如果设置相对较长的验证码有效时间,那么攻击者就可以用较低的频率爆破。反之,验证码有效时间相对较短,则对爆破的频率提出高要求,这既考验攻击者的硬件和软件,也考验网络传输和服务端压力......
  • web基础漏洞-逻辑漏洞
    1、介绍逻辑漏洞是由于业务代码的逻辑缺失或者错误,导致的漏洞。2、场景2.1可爆破可猜解弱账号密码验证码登录凭证cookie或token,以及访问口令优惠券id,图片id,博客id等找回密码的问答2.2步骤可跳过(1)某功能分为多个页面/接口,可以直接请求后面的页面/接口(2)某功能基......
  • 安卓开发基础适配器,SimpleAdapter 快速演示
    第一,主视图如下:<?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent&qu......