视图集及路由 关联序列化

视图集及路由 关联序列化,第1张

1创建新项目的准备工作 1.1命令框内创建新项目

打开指定文件夹,在路径位置输入cmd打开命令行
django-admin startproject 项目名 创建项目

1.2在新项目内创建子应用

python manage.py startapp 子应用名

1.3注册子应用

在settings.py文件内注册子应用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    '创建的子应用名'    #注册子应用
]
1.5配置数据库

在settings.py文件内

# 配置数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # 使用mysql数据库
        'HOST': 'localhost',  # 主机
        'PORT': 3306,  		# 端口
        'USER': 'root',  	# 数据库的用户名
        'PASSWORD': '密码', # 数据库的密码
        'NAME': '创建的数据库名',  	# 数据库的名字
    }
}
1.6修改语言和时区

在settings.py文件内

LANGUAGE_CODE = 'zh-Hans'  #语言

TIME_ZONE = 'Asia/Shanghai'  #时区
1.8常用的mysql代码语句

查看所有数据库: show databases;
创建数据库: create database 数据名 charset=utf8;
删除数据库: drop database 数据库名;
调用数据库: use 数据库名;
查看数据库下的所有表: show tables;
查看表结构: desc 表名;
查看表中的所有数据: select * from 表名;

1.9安装数据库

在跟项目名同名的文件夹内init.py文件里安装

import pymysql
pymysql.install_as_MySQLdb()
1.9.1创建模型类

在子应用文件夹里的models.py创建

from django.db import models

# Create your models here.
class Kinds(models.Model):
    kind_name=models.CharField(max_length=20,verbose_name='种类名称')
    class Meta:
        verbose_name='种类表'
        verbose_name_plural=verbose_name
        db_table='kinds'
    def __str__(self):
        return self.kind_name

class Goods(models.Model):
    name=models.CharField(max_length=20,verbose_name='商品名')
    price=models.IntegerField(verbose_name='单价')
    number=models.IntegerField(verbose_name='数量')
    sale_out=models.BooleanField(default=False,verbose_name='售空')
    kind=models.ForeignKey(Kinds,on_delete=models.CASCADE,verbose_name='商品种类')
    class Meta:
        verbose_name='商品表'
        verbose_name_plural=verbose_name
        db_table='goods'
    def __str__(self):
        return self.name
1.9.2创建好模型类后进行迁移

在项目内终端执行
生成迁移文件:python manage.py makemigrations
执行迁移:python manage.py migrate
如果迁移出错,把数据库删了创建新的数据库,生成的迁移文件也删了,重新执行上面2个步骤

1.9.3创建超级用户

创建超级用户 (python终端内运行)
python manage.py createsuperuser
电子邮件地址直接回车跳过
(前后密码要一致)
如果出现cryptography报错就python终端内安装
pip install cryptography

2.在子应用的admin.py文件中添加代码,注册表,不然admin控制台没办法管理这个表

from django.contrib import admin
from myapp.models import Kinds,Goods
# Register your models here.
admin.site.register(Kinds)
admin.site.register(Goods)

3.运行项目,在admin页面添加数据

前后端分离

前端主要追求的是美观、流畅、兼容
后端追求的是三高,高性能、高并发、高可用

什么是restful风格

增删改查
GET:获取数据
POST:提交数据,创建数据
PUT:提交数据,更新数据
DELETE:删除数据
状态码
200 [GET] 获取数据时的状态码
201 [POST/PUT/PATCH] 添加或创建数据
204 [DELETE] 用于删除的状态码

2.DRF工程 下载第三方模块

在黑窗口内进行安装
pip install djangorestframework

在settings.py文件内注册

跨域也顺便弄好

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',#跨域
    'myapp',
    'rest_framework',
]
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware'   # 添加跨域中间件
]
CORS_ORIGIN_ALLOW_ALL = True    #配置参数,允许所有源访问
序列化器自动获取

在子应用中创建一个serializers.py文件写入类方法

#导包
from rest_framework import serializers
from myapp.models import Kinds,Goods
class Kindsser(serializers.ModelSerializer):
    class Meta:
        model=Kinds
        fields='__all__'
class Goodsser(serializers.ModelSerializer):
    class Meta:
        model=Goods
        fields='__all__'
#外键序列化
#只能进行序列化 只能查询 不能进行反序列化
class Goodsser2(serializers.ModelSerializer):
    ##1使用外键表的str方法进行序列化   #可以展示老师姓名
    # teacher=serializers.StringRelatedField()
    #2指定字段序列化   # 可以展示老师姓名
    # teacher=serializers.SlugRelatedField(read_only=True,slug_field='tea_name')
    #3使用外键表的主键(id)进行序列化
    # teacher=serializers.PrimaryKeyRelatedField(read_only=True)
    #4使用自定义方法进行序列化,字段自定义    #可以展示老师姓名
    kind_name=serializers.SerializerMethodField(read_only=True)
    #函数名以get_开头,再加上自定义字段名:  obj是模型类对象
    def get_kind_name(self,obj):
    return obj.kind.kind_name
    class Meta:
        model=Goods
        fields='__all__'
视图集是什么

视图集简单来说就是一群视图逻辑 *** 作的功能合集,并可采用路由映射的方式进行功能选择,编写的内置逻辑方法不再是使用请求命名,而是使用功能来进行命名

混入类的视图集概念

ModelViewSet从类继承 GenericAPIView,并包括用于各种动作实现方式中,通过在各种混入类的行为混合,包含了 .list.retrieve.create.update.partial_update、和 .destroy等方法,继承ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestroyModelMixin

drf官方文档 增删改查

学生表跟老师表的增删改查

from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.models import Kinds,Goods
from myapp.serializers import Kindsser,Goodsser,Goodsser2
from rest_framework.generics import ListAPIView
from rest_framework.viewsets import ModelViewSet
#使用ModelViewSet实现增删查改
from rest_framework.viewsets import ModelViewSet
class Kindset(ModelViewSet):
    queryset = Kinds.objects.all()
    serializer_class = Kindsser
class Goodset(ModelViewSet):
    queryset = Goods.objects.all()
    serializer_class = Goodsser
#外键序列化器查询商品信息
class Goodsveiw3(ListAPIView):
    # 绑定查询结果集
    queryset = Goods.objects.all()
    # 指定序列化器
    serializer_class = Goodsser2
class Goodsview4(APIView):
    #根据id查询对应的商品
    def get(self,request,id):
        goo_data=Goods.objects.filter(kind_id=id)
        ser=Goodsser2(instance=goo_data,many=True)
        return Response(ser.data,status=200)

配置路由

from django.contrib import admin
from django.urls import path
from myapp import views
from rest_framework import routers
urlpatterns = [
    path('goo2/',views.Goodsveiw3.as_view()),
    path('goo2//',views.Goodsview4.as_view()),

]
# 1.生成路由对象
router=routers.SimpleRouter()
# router=routers.DefaultRouter()
#2.使用路由对象生成路由
#参数1:路径的名字  2:使用的视图集 3:给生成的路由起一个名字
router.register('kind',views.Kindset,'kind')
router.register('good',views.Goodset,'good')
#3.路由追加
urlpatterns+=router.urls
两种路由生成方式区别及根路由是什么
  • SimpleRouter:最基本的路由映射方式,只会将视图集具备的混入类功能进行路由的生成
  • DefaultRouter:对比与SimpleRouter更加高级,包含有drf根页面的路由,不只是视图集所包含的视图部分
创建vue项目

打开黑窗口 输入
vue create 项目名
选择自定义
只选择路由跟vuex安装

vue准备工作 1安装axios

运行终端输入
npm install --save axios

2实现跨域

在vue根目录创建vue.config.js文件

module.exports={
    devServer:{
        proxy:'http://127.0.0.1:8000/' 
    }
}
3封装方法

在vue项目创建utils文件年里创建request.js文件

import Axios from 'axios'

//常用来封装
export function get(url,params){
    return Axios.get(url,params)
}
export function post(url,params){
    return Axios.post(url,params)
}
export function put(url,params){
    return Axios.put(url,params)
}
export function del(url,params){
    return Axios.delete(url,params)
}
创建vue文件

在views文件夹内创建vue文件
实现增删改查
种类页面vue文件

<template>
    <div>种类页面div>
    {{kinlist}}
    <table align='center' width='300px' border="1px" cellspacing='0px'>
        <tr>
            <td>编号td>
            <td>种类td>
            <td> *** 作td>
        tr>
        <tr v-for="(i,j) in kinlist" :key="j">
            <td>{{i.id}}td>
            <td>
                <router-link :to="{name:'Goods',params:{id:i.id}}">
                    {{i.kind_name}}
                router-link>
            td>
            <td><button @click="remove(i.id)">删除button>td>
        tr>
    table>
    种类:<input type="text" v-model="kind.kind_name">
    <button @click="add">添加button>
template>

<script>
import { del, get, post } from '@/utils/request'
export default {
    data(){
        return{
            kinlist:[],
            kind:{kind_name:""}
        }
    },
    mounted(){
        get('kind/')
        .then((result) => {
            console.log(result)
            this.kinlist=result.data
        }).catch((err) => {
            console.log(err)
        });
    },
    methods:{
        add(){
            post('kind/',this.kind)
            .then((result) => {
                console.log(result)
            }).catch((err) => {
                console.log(err)
            });
        },
        remove(id){
            let url='kind/'+id+'/'
            del(url)
            .then((result) => {
                console.log(result)
                alert('删除成功')
            }).catch((err) => {
                console.log(err)
            });
        }
    }

}
script>

<style>

style>

学生页面vue文件

<template>
    <div>商品页面div>
    {{goolist}}
    <table align='center' border="1px" width='500px' cellspacing='0px'>
        <tr>
            <td>编号td>
            <td>商品td>
            <td>单价td>
            <td>数量td>
            <td>售空td>
            <td>种类td>
            <td> *** 作td>
        tr>
        <tr v-for="(i,j) in goolist" :key="j">
            <td>{{i.id}}td>
            <td>{{i.name}}td>
            <td>{{i.price}}td>
            <td>{{i.number}}td>
            <td>{{i.sale_out}}td>
            <td>{{i.kind_name}}td>
            <td>
                <button @click="remove(i.id)">删除button>
                <button @click="getup(i.id)">修改button>
            td>
        tr>
    table>
    商品: <input type="text" v-model="upgoo.name"><br>
    单价: <input type="text" v-model="upgoo.price"><br>
    数量: <input type="text" v-model="upgoo.number"><br>
    售空: <input type="checkbox" v-model="upgoo.sale_out"><br>
    
    商品编号: 
    <select v-model="upgoo.kind">
        <option v-for="(i,j) in kinlist" :key="j">{{i.id}}option>
    select><br>
    <button @click="update">修改button>
template>

<script>
import { del, get, put } from '@/utils/request'
export default {
    data(){
        return{
            kin_id:this.$route.params.id,
            goolist:[],
            kinlist:[],
            id:0,
            upgoo:{
                name:'',
                price:0,
                number:0,
                sale_oyt:false,
                kind:0,
            }
        }
    },
    mounted(){
        this.getgoo();
        this.getkin()
    },
    methods:{
        getkin(){
            // 获取种类数据
            get('kind/')
            .then((result) => {
                console.log(result)
                this.kinlist=result.data
            }).catch((err) => {
                console.log(err)
            });
        },
        getgoo(){
            // 获取对应的商品信息
            let url='goo2/'+this.kin_id+'/'
            get(url)
            .then((result) => {
                console.log(result)
                this.goolist=result.data
            }).catch((err) => {
                console.log(err)
            });
        },
        remove(id){
            // 删除数据
            let url='good/'+id+'/'
            del(url)
            .then((result) => {
                console.log(result)
                this.getgoo()
            }).catch((err) => {
                console.log(err)
            });
        },
        getup(id){
            // 获取数据
            let url='good/'+id+'/'
            get(url)
            .then((result) => {
                console.log(result)
                this.upgoo=result.data
                this.id=result.data.id
            }).catch((err) => {
                console.log(err)
            });
        },
        update(){
            // 修改数据信息
            let url='good/'+this.id+'/'
            put(url,this.upgoo)
            .then((result) => {
                console.log(result)
                this.getgoo()
            }).catch((err) => {
                console.log(err)
            });
        }
    }
}
script>

<style>

style>
安装路由
import province from '../views/student2/Province.vue'
import Student from '../views/student2/Student.vue'
const routes = [
  {
    path: '/',//视图页面
    name: 'Province',
    component: province
  },
  {
    path: '/student',//视图页面
    name: 'Student',
    component: Student
  },

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/916201.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存