单爆手

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 参考https://github.com/rfjer/autoAdmin/

https://github.com/rfjer/autoAdmin/blob/master/apps/users/serializers.py

用户功能:
    创建用户        <<=post
    获取用户列表    <<= get
        分页        
        搜索
    修改用户        <=patch/put
    删除用户         <=delete
我把分成用户注册登录是一个功能,用户列表修改是一个功能

新建运维平台项目:


1.创建数据库:

[vagrant@CentOS ~]$ sudo su - root
[root@CentOS ~]# mysql -uroot
CREATE DATABASE `devops_test` /*!40100 DEFAULT CHARACTER SET utf8 */;

创建虚拟环境:

sudo su - vagrant
sudo /usr/local/python36/bin/pip3 install virtualenv
/usr/local/python36/bin/virtualenv ./python36env
source ./python36env/bin/activate
cd /vagrant/

2.关闭防火墙:

sudo systemctl stop firewalld

sudo systemctl disable firewalld.service

3.安装工具: pip list

 Django 2.2.1
 pip install coreapi-cli
 pip install djangorestframework
 pip install django-apscheduler pip install tencentcloud-sdk-python
 pip install django-filter
 pip install requests -i https://pypi.douban.com/simple/ 
 pip install pymysql
 pip install django-rest-swagger
 pip install django-cors-headers
 pip install djangorestframework-jwt
4.创建项目:
django-admin startproject devops (python36env) [vagrant@CentOS devops]$ python manage.py runserver 0.0.0.0:8000
pycharm设置远程连接此虚拟环境中的django项目!!
5.创建用户app: (python36env) [vagrant@CentOS devops]$ pwd
/vagrant/devops (python36env) [vagrant@CentOS devops]$ django-admin startapp users (python36env) [vagrant@CentOS devops]$ mkdir apps (python36env) [vagrant@CentOS devops]$ mv users apps/ settings.py配置:
import os
import sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,os.path.join(BASE_DIR, "apps"))

SECRET_KEY = '9vg^(z0ay7ii873g1!7--##r(r#=iisz3wn@mzkxbmx_5iw7))'

DEBUG = True

ALLOWED_HOSTS = []

AUTH_USER_MODEL = 'users.User'

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'users',
    'corsheaders',
    'django_apscheduler',
    'django_filters'
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:8000',
)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'devops.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'devops.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'devops_test',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'OPTIONS':{
            'init_command':"SET sql_mode='STRICT_TRANS_TABLES'",
            'charset':'utf8mb4',
        },
    }
}


AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False


STATIC_URL = '/static/'

from rest_framework.settings import api_settings

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'devops.paginations.Pagination',
    'PAGE_SIZE': 10,
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
    # 'DEFAULT_PERMISSION_CLASSES': (
    #     'rest_framework.permissions.IsAuthenticated',
    #     'rest_framework.permissions.DjangoModelPermissions',
    # ),
    # 'DEFAULT_AUTHENTICATION_CLASSES': (
    #     'rest_framework.authentication.SessionAuthentication',
    #     'rest_framework.authentication.BasicAuthentication',
    #     'rest_framework.authentication.TokenAuthentication',
    # ),
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}

## qcloud
QCLOUD_SECRETID = "AKIDFaq5EbGxiQx22qzUL2XtCJJ7j9NQuyTq"
QCLOUD_SECRETKEY = "LTP8fz72lOr8D8reFerunUyGQN7f4LTP"

# LOGGING = {
#     'version': 1,
#     'disable_existing_loggers': False,
#     'loggers': {
#         'reboot': {
#             'handlers': ["reboot"],
#             'level': 'DEBUG',
#             'propagate': True
#         },
#         "django": {
#             'handlers': ["django"],
#             'level': 'DEBUG',
#             'propagate': True
#         },
#         "django.server": {
#             'handlers': ["django_server"],
#             'level': 'DEBUG',
#             "propagate": True
#         },
#         "django.db.backends": {
#             "propagate": False,
#             'level': 'DEBUG',
#             'handlers': ["db_backends"]
#         }
#     },
#     'handlers': {
#         "db_backends": {
#             'level': 'DEBUG',
#             'class': 'logging.FileHandler',
#             'filename': '/tmp/db_backends.log',
#             'formatter': 'default'
#         },
#         'reboot': {
#             'level': 'DEBUG',
#             'class': 'logging.StreamHandler',
#             'formatter': 'simple',
#         },
#         'file': {
#             'level': 'DEBUG',
#             'class': 'logging.FileHandler',
#             'filename': '/tmp/django.log',
#             'formatter': 'json',
#         },
#         'django': {
#             'level': 'DEBUG',
#             'class': 'logging.FileHandler',
#             'filename': '/tmp/default.log',
#             'formatter': 'simple',
#         },
#         'django_server': {
#             'level': 'DEBUG',
#             'class': 'logging.FileHandler',
#             'filename': '/tmp/django_server.log',
#             'formatter': 'simple',
#         },
#     },
#     'formatters': {
#         'json': {
#             'format': '{"levelname":"%(levelname)s","asctime":"%(asctime)s","module":"%(name)s","fullpath":"%(pathname)s","funcName":"%(funcName)s","lineno":"%(lineno)s","message":"%(message)s"}'
#         },
#         'reboot': {
#             'format': '%(asctime)s - %(pathname)s:%(lineno)d[%(levelname)s] - %(message)s'
#         },
#         'simple': {
#             'format': '%(name)s %(asctime)s %(levelname)s %(message)s'
#         },
#         'verbose': {
#             'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
#         },
#         "default": {
#             "format": '%(asctime)s %(name)s %(lineno)s %(levelname)s  %(message)s',
#             "datefmt": "%Y-%m-%d %H:%M:%S"
#         }
#     },
#     "root": {
#         'handlers': ["file"],
#         'level': 'DEBUG',
#     }
# }

DOMAIN = "@51reboot.com"

后端实现:
6.users/models.py:

from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser, Group

class User(AbstractUser):
    name = models.CharField("姓名", max_length=32, null=True, help_text="姓名")
    phone = models.CharField("电话", max_length=11, null=True, help_text="手机号")

    class Meta:
        verbose_name = "用户"
        ordering = ["id"]
        db_table = 'auth_user'

    def __str__(self):
        return self.username

7.users/views.py:

from rest_framework import viewsets, permissions, mixins
from .serializers import UserSerializer, UserRegSerializer
from .filters import UserFilter
from django_filters.rest_framework import DjangoFilterBackend
from django.contrib.auth import get_user_model
User = get_user_model()


class UserViewset(mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   viewsets.GenericViewSet):
    """
    retrieve:
        获取指定user记录
    list:
        获取user列表
    update:
        更新user记录
    partial_update:
        更新user的部门字段
    destroy:
        删除user记录
    """
    queryset = User.objects.filter(is_superuser=False)
    serializer_class = UserSerializer
    filter_class=UserFilter
    filter_fields = ("username",)
#有两个地方可控制你提交哪些方法:一个是此处的视图层,一个是序列化中(序列化中控制的是具体要怎么个做法动作)
#UserRegViewset类想支持什么方法在此引入就好了
class UserRegViewset(viewsets.GenericViewSet,
                     mixins.CreateModelMixin,
                     mixins.UpdateModelMixin):
    """
    create:
        用户注册
    partial_update:
        修改密码
    update:
        修改密码
    """
    queryset = User.objects.all()
    serializer_class = UserRegSerializer

8.users/serializers.py:

from rest_framework import serializers
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from django.conf import settings
User = get_user_model()

#控制具体动作有哪些
class UserSerializer(serializers.ModelSerializer):
    """
    用户序列化类
    """
    #控制的你是返回的格式:
    last_login  = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S",
                                            label="上次登录时间",
                                            help_text="上次登录时间")

    # 控制往前端返回哪些字段:
    class Meta:
        model = User
        fields = ("id", "username", "name", "phone", "email", "is_active", "last_login")
    #想修改哪些字段可在此方法中控制:
    def update(self, instance, validated_data):
        instance.phone = validated_data.get("phone", instance.phone)
        instance.is_active = validated_data.get("is_active", instance.is_active)
        instance.save()
        return instance


class UserRegSerializer(serializers.ModelSerializer):
    """
    用户注册序列化类
    """
    #把密码处理成密文
    password = serializers.CharField(style={"input_type": "password"},
                                     label="密码",
                                     write_only=True,
                                     help_text="密码")
   #验证
    def validate(self, attrs):
        attrs["is_active"] = False #默认创建完的用户不可直接登录
        #给用户自动加email地址
        attrs["email"] = "{}{}".format(attrs['username'], settings.DOMAIN)
        return attrs
    #此create可不要,但不要的结果是密码直接存进去了
    def create(self, validated_data):
        instance = super(UserRegSerializer, self).create(validated_data=validated_data)
        instance.set_password(validated_data["password"])
        instance.save()
        return instance

    def update(self, instance, validated_data):
        password =  validated_data.get("password", None)
        if password:
            instance.set_password(password)
            instance.save()
        return instance
    class Meta:
        model = User
        #序列化时返回的数据
        fields = ("username", "password", "name", "id", "phone")

9.users/router.py:

from rest_framework.routers import DefaultRouter
from .views import UserViewset, UserRegViewset
router = DefaultRouter()
router.register("users", UserViewset, basename="users")
router.register("userReg", UserRegViewset, basename="userReg")

10.users/urls.py:

from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from rest_framework.documentation import include_docs_urls
from users.router import router as user_router
# from resources.router import router as resources_router
router = DefaultRouter()
router.registry.extend(user_router.registry)
# router.registry.extend(resources_router.registry)


from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
    url(r'^api/', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls')),
    url(r'^docs/', include_docs_urls("51reboot接口文档")),
    url(r'^api-token-auth/', obtain_auth_token)
]

11.users/filters.py:

import django_filters
from django.contrib.auth import get_user_model

User = get_user_model()


class UserFilter(django_filters.FilterSet):
    username = django_filters.CharFilter(lookup_expr="icontains")

    class Meta:
        model = User
        fields=["username"]

12.devops/urls.py:

import django_filters
from django.contrib.auth import get_user_model

User = get_user_model()


class UserFilter(django_filters.FilterSet):
    username = django_filters.CharFilter(lookup_expr="icontains")

    class Meta:
        model = User
        fields=["username"]

13.devops/paginations.py:

from rest_framework.pagination import PageNumberPagination


class Pagination(PageNumberPagination):
    def get_page_size(self, request):
        try:
            page_size = int(request.query_params.get("page_size", -1))
            if page_size >= 0:
                return page_size
        except:
            pass
        return self.page_size
数据迁移报错:
migration执行没有报错,但是执行migrate就报错:
Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'.
解决:删除数据库,新建一个跟原来一样名字的数据库,就解决了

 

启动项目:

(python36env) [vagrant@CentOS devops]$ python manage.py createsuperuser
用户名: admin
电子邮件地址: admin@51reboot.com
Password:  123456

(python36env) [vagrant@CentOS devops]$ python manage.py runserver 0.0.0.0:8000

效果如下:

 

一. 用户注册登陆与列表 

1.后端实现:后端需要:写序列化/视图/路由

创建测试用户的数据:

(python36env) [vagrant@CentOS devops]$ python manage.py shell                                          
In [2]: from django.contrib.auth import get_user_model                                               
In [3]: User = get_user_model()                                                                      
In [4]: def create_user(name): 
   ...:     for i in range(1,20): 
   ...:         username = "{}-{}".format(name,i) 
   ...:         User.objects.create_user(username, "{}@51reboot.com".format(username),"12345678") 
   ...:                                                                                              

In [5]: create_user("rock")
In [6]: create_user("panda")                                                                         

In [7]: create_user("wd") 
In [8]: User.objects.all().delete()  ---不想要时可用此命令清空数据

(1).users/serializers.py:

使用模型序列化,那create方法就可不用写(因为它默认把create做好了),但前提是我需要把数据给准备好,而这里有些数据是没有的,如email地址,而注册时我要求是填入用户名,密码,联系电话这些是必须要的,但是没有填邮件地址。那这个是可以改的---根据用户再来一个DOMAIN域名

 (1)settings.py中加入DOMAIN---让自动生成邮件域名

DOMAIN = "@51reboot.com"
from rest_framework import serializers
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from django.conf import settings
User = get_user_model()

#控制具体动作有哪些
class UserSerializer(serializers.ModelSerializer):
    """
    用户序列化类
    """
    #控制的你是返回的格式:
    last_login  = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S",
                                            label="上次登录时间",
                                            help_text="上次登录时间")

    # 控制往前端返回哪些字段:
    class Meta:
        model = User
        fields = ("id", "username", "name", "phone", "email", "is_active", "last_login")
    #想修改哪些字段可在此方法中控制:
    def update(self, instance, validated_data):
        instance.phone = validated_data.get("phone", instance.phone)
        instance.is_active = validated_data.get("is_active", instance.is_active)
        instance.save()
        return instance


class UserRegSerializer(serializers.ModelSerializer):
    """
    用户注册序列化类
    """
    #把密码处理成密文
    password = serializers.CharField(style={"input_type": "password"},
                                     label="密码",
                                     write_only=True,
                                     help_text="密码")
   #验证
    def validate(self, attrs):
        attrs["is_active"] = False #默认创建完的用户不可直接登录
        #给用户自动加email地址
        attrs["email"] = "{}{}".format(attrs['username'], settings.DOMAIN)
        return attrs
    #此create可不要,但不要的结果是密码直接存进去了
    def create(self, validated_data):
        instance = super(UserRegSerializer, self).create(validated_data=validated_data)
        instance.set_password(validated_data["password"])
        instance.save()
        return instance

    def update(self, instance, validated_data):
        password =  validated_data.get("password", None)
        if password:
            instance.set_password(password)
            instance.save()
        return instance
    class Meta:
        model = User
        #序列化时返回的数据
        fields = ("username", "password", "name", "id", "phone")

( 2).users/views.py:

from rest_framework import viewsets, permissions, mixins
from .serializers import UserSerializer, UserRegSerializer
from .filters import UserFilter
from django_filters.rest_framework import DjangoFilterBackend
from django.contrib.auth import get_user_model
User = get_user_model()


class UserViewset(mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   viewsets.GenericViewSet):
    """
    retrieve:
        获取指定user记录
    list:
        获取user列表
    update:
        更新user记录
    partial_update:
        更新user的部门字段
    destroy:
        删除user记录
    """
    queryset = User.objects.filter(is_superuser=False)
    serializer_class = UserSerializer
    filter_class=UserFilter
    filter_fields = ("username",)
#有两个地方可控制你提交哪些方法:一个是此处的视图层,一个是序列化中(序列化中控制的是具体要怎么个做法动作)
#UserRegViewset类想支持什么方法在此引入就好了
class UserRegViewset(viewsets.GenericViewSet,
                     mixins.CreateModelMixin,
                     mixins.UpdateModelMixin):
    """
    create:
        用户注册
    partial_update:
        修改密码
    update:
        修改密码
    """
    queryset = User.objects.all()
    serializer_class = UserRegSerializer

(3).users/router.py:

from rest_framework.routers import DefaultRouter
from .views import UserViewset, UserRegViewset
router = DefaultRouter()
router.register("users", UserViewset, basename="users")
router.register("userReg", UserRegViewset, basename="userReg")

(4)devops/urls.py:

from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from rest_framework.documentation import include_docs_urls
from groupUsers .views import GroupUsersViewset
from users.router import router as user_router
router = DefaultRouter()
router.registry.extend(user_router.registry)
#

from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
    url(r'^api/', include(router.urls)),  
    url(r'^', include('resources.urls')),
    url(r'^api-auth/', include('rest_framework.urls')),
    url(r'^docs/', include_docs_urls("51reboot接口文档")),
    url(r'^api-token-auth/', obtain_auth_token)
]

  上述中是以api开头的全部交给router.urls去处理,,因为到时我前端和后端可能放在一台服务器上,然后调动的时候只要不是api开头的全部交给nginx去处理,以api开头则交给django去处理。

效果如下:

 

 

 

 二.展示用户列表--打通前后端

1.vue环境搭建:

参考https://www.cnblogs.com/dbslinux/p/13180500.html

下载vue模版: 

 F:\devops\data\web>git clone https://github.com/gxhsh/vueAdmin-template.git

安装nodejs:  F:\devops\data\web\vue-admin-template>npm install --registry=https://registry.npm.taobao.org

 F:\devops\data\web\vue-admin-template>npm run dev 

2.配置:

 (2)src/permission.js ---取消权限

import router from './router'
// import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
// import { Message } from 'element-ui'
// import { getToken } from '@/utils/auth' // 验权

// const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
  NProgress.start()
  next()
  // if (getToken()) {
  //   if (to.path === '/login') {
  //     next({ path: '/' })
  //   } else {
  //     if (store.getters.roles.length === 0) {
  //       store.dispatch('GetInfo').then(res => { // 拉取用户信息
  //         next()
  //       }).catch(() => {
  //         store.dispatch('FedLogOut').then(() => {
  //           Message.error('验证失败,请重新登录')
  //           next({ path: '/login' })
  //         })
  //       })
  //     } else {
  //       next()
  //     }
  //   }
  // } else {
  //   if (whiteList.indexOf(to.path) !== -1) {
  //     next()
  //   } else {
  //     next('/login')
  //     NProgress.done()
  //   }
  // }
})

router.afterEach(() => {
  NProgress.done() // 结束Progress
})

效果如图

 (3)重新指向路由config/index.js

(4)开发环境配置成本机config/dev.env.js

  BASE_API: '"http://127.0.0.1:8000"',

(5)线上环境配置config/rpod.env.js

 BASE_API: '"http://127.0.0.1:8000"',

(6)去掉不需要的路由router/index.js

 

 最终效果如下--这就是我的前端页面:

 

 

 注意上述图中url有#开头的路由,我可把它改成history模式---即/目录名/目录名。但如果以#开头的路由那我的nginx不用作任何处理,如果是history模式则需nginx支持--https://router.vuejs.org/zh/guide/essentials/history-mode.html

打开 router/index.jx中的

mode: 'history',
效果如下:

3.用户展示

(1)router/index.js添加前端路由

  {
    path: '/users',
    component: Layout,
    name: 'users',
    meta: { title: '用户管理', icon: 'example' },
    children: [
      {
        path: 'user',
        name: 'user',
        component: () => import('@/views/users/user'),   <<<--引用下面定义的路由
        meta: { title: '用户', icon: 'table' }
      }
    ]
  },

(2)前端视图views/users/user.vue

<template>
  <div class="app-container">
    用户列表: {{ msg }}
  </div>
</template>

<script>
  export default {
    name: 'UserList',
    data() {
      return {
        msg: 'rock'
      }
    }
  }
</script>

<style scoped>

</style>

效果如图:

浏览器装vue插件https://www.gugeapps.com/

 4.获取后端数据---在api中

 (1)api/user.js

import request from '@/utils/request'

export function getUserList(params) {
  return request({
    url: '/api/users/',
    method: 'get',
    params
  })
}

(2)users/user.vue中引入

................
<script> import { getUserList } from '@/api/user' export default { name: 'UserList', data() { return { msg: 'rock' } }, created() { this.fetchUserList() }, methods: { fetchUserList() { getUserList() } } } </script>

报如下错:

(3)解决跨域参考github

还不能解决跨域则如下配置:

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'http://127.0.0.1:8000',
))

(4) 解决前端request拦截器utils/request.js

import axios from 'axios'
import { Message } from 'element-ui'
// import store from '../store'
// import { getToken } from '@/utils/auth'

// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 15000 // 请求超时时间
})

// request拦截器
// service.interceptors.request.use(config => {
//   if (store.getters.token) {
//     config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
//   }
//   return config
// }, error => {
//   // Do something with request error
//   console.log(error) // for debug
//   Promise.reject(error)
// })

// respone拦截器
service.interceptors.response.use(
  response => {
  /**
  * code为非20000是抛错 可结合自己业务进行修改
  */
    return response.data
    // const res = response.data
    // if (res.code !== 20000) {
    //   Message({
    //     message: res.message,
    //     type: 'error',
    //     duration: 5 * 1000
    //   })
    //
    //   // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
    //   if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
    //     MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
    //       confirmButtonText: '重新登录',
    //       cancelButtonText: '取消',
    //       type: 'warning'
    //     }).then(() => {
    //       store.dispatch('FedLogOut').then(() => {
    //         location.reload()// 为了重新实例化vue-router对象 避免bug
    //       })
    //     })
    //   }
    //   return Promise.reject('error')
    // } else {
    //   return response.data
    // }
  },
  error => {
    console.log('err' + error)// for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

(5)users/user.vue

<template>
  <div class="app-container">
    用户列表:
  </div>
</template>

<script>
import { getUserList } from '@/api/user'

export default {
  name: 'UserList',
  data() {
    return {
      userList: []
    }
  },
  created() {
    this.fetchUserList()
  },
  methods: {
    fetchUserList() {
      getUserList().then(res => {
        this.userList = res.results
      })
    }
  }
}
</script>

效果如图:已拿到数据

 5.将数据展示到页面----去element ui拿组件即可--https://element.eleme.io/#/

 users/user.vue:

<template>
  <div class="app-container">
    <el-table
      :data="userList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="username"
        label="username"/>
      <el-table-column
        prop="name"
        label="姓名"/>
      <el-table-column
        prop="phone"
        label="电话"/>
      <el-table-column
        prop="email"
        label="email"/>
      <el-table-column
        prop="is_active"
        label="状态">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
        </template>
      </el-table-column>
      <el-table-column
        prop="last_login"
        label="last_login"/>
      <el-table-column
        fixed="right"
        label="操作"
        width="100">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
。。。。。。。

效果出来了:

 三.修改用户状态:

(1)api/user.jss

......
export function modifyUser(id, data) {
  return request({
    url: `/api/users/${id}/`,
    method: 'patch',
    data
  })
}

(2)users/user.vue

<template>
  <div class="app-container">
    <el-table
      :data="userList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="username"
        label="username"/>
      <el-table-column
        prop="name"
        label="姓名"/>
      <el-table-column
        prop="phone"
        label="电话"/>
      <el-table-column
        prop="email"
        label="email"/>
      <el-table-column
        prop="is_active"
        label="状态">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
        </template>
      </el-table-column>
      <el-table-column
        prop="last_login"
        label="last_login"/>
      <el-table-column
        fixed="right"
        label="操作"
        width="100">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { getUserList, modifyUser } from '@/api/user'

export default {
  name: 'UserList',
  data() {
    return {
      userList: []
    }
  },
  created() {
    this.fetchUserList()
  },
  methods: {
    fetchUserList() {
      getUserList().then(res => {
        this.userList = res.results
      })
    },
    handleUserStatusChange(obj) {
      modifyUser(obj.id, { is_active: obj.is_active }).then(() => {
        this.$message({
          message: `修改 ${obj.name} 的状态成功`,
          type: 'success'
        })
      })
    }
  }
}
</script>

效果如下:

 四.添加用户/修改用户--此功能把它定义成组件

https://element.eleme.io/#/zh-CN/component/installation

我要的是弹框效果

 1.users/components/addUserForm.vue

<template>
  <div class="add-user-form">
    <el-dialog :visible.sync="visible" title="用户信息" @close="handleClose">
      <el-form ref="addUserForm" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="登陆名:" prop="username">
          <el-input v-model="form.username" placeholder="请输入登陆名"/>
        </el-form-item>
        <el-form-item label="姓名:" prop="name">
          <el-input v-model="form.name" placeholder="请输入姓名"/>
        </el-form-item>
        <el-form-item label="密码:" prop="password">
          <el-input v-model="form.password" type="password" placeholder="请输入密码"/>
        </el-form-item>
        <el-form-item label="手机号:" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入手机号"/>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm">立即创建</el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="handleClose">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
  import { addUser } from '@/api/user'
  export default {
    name: 'AddUserForm',
    props: {
      value: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        visible: false,
        form: {
          username: '',
          name: '',
          password: '',
          phone: ''
        },
        rules: {
          username: [
            { required: true, message: '请输入用户名', trigger: 'blur' }
          ],
          name: [
            { required: true, message: '请输入用户姓名', trigger: 'blur' }
          ],
          password: [
            { required: true, message: '请输入密码', trigger: 'blur' }
          ],
          phone: [
            { required: true, message: '请输入联系电话', trigger: 'blur' }
          ]
        }
      }
    },
    watch: {
      value(val) {
        this.visible = val
      }
    },
    methods: {
      handleClose() {
        this.visible = false
        this.$emit('input', false)
        this.resetForm()
      },
      resetForm() {
        this.$refs.addUserForm.resetFields()
      },
      submitForm() {
        this.$refs.addUserForm.validate((valid) => {
          if (valid) {
            addUser(this.form).then(() => {
              this.$message({
                message: `创建用户 ${this.form.name} 成功`,
                type: 'success'
              })
              this.handleClose()
              this.$emit('fetch')
            })
          } else {
            console.log('error submit!!')
            return false
          }
        })
      }
    }
  }
</script>

2.api/user.js

import request from '@/utils/request'

export function getUserList(params) {
  return request({
    url: '/api/users/',
    method: 'get',
    params
  })
}

export function getUser(userId) {
  return request({
    url: `/api/users/${userId}/`,
    method: 'get'
  })
}

export function modifyUser(id, data) {
  return request({
    url: `/api/users/${id}/`,
    method: 'patch',
    data
  })
}

export function addUser(data) {
  return request({
    url: `/api/userReg/`,
    method: 'post',
    data
  })
}

3.users/user.vue

<template>
  <div class="app-container">
    <el-row>
      <el-col :span="12">
        <el-input v-model="params.username" placeholder="搜索用户名" @keyup.enter.native="handleSearch">
          <el-button slot="append" icon="el-icon-search" @click="handleSearch"/>
        </el-input>
      </el-col>
      <el-col :span="12" align="right" style="padding-right:20px;">
        <el-button type="primary" @click="addUserVisible=true">添加用户</el-button>
      </el-col>
    </el-row>
    <el-table
      :data="userList"
      stripe
      style="width: 100%">
      <el-table-column
        prop="username"
        label="username"/>
      <el-table-column
        prop="name"
        label="姓名"/>
      <el-table-column
        prop="phone"
        label="电话"/>
      <el-table-column
        prop="email"
        label="email"/>
      <el-table-column
        prop="is_active"
        label="状态">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
        </template>
      </el-table-column>
      <el-table-column
        prop="last_login"
        label="last_login"/>
      <el-table-column
        fixed="right"
        label="操作"
        width="100">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-row v-show="total>10" type="flex" justify="center" style="padding-top:20px;">
      <el-pagination
        :total="total"
        layout="prev, pager, next"
        background
        @current-change="handleChange" />
    </el-row>
    <AddUserForm v-model="addUserVisible" @fetch="handleFetch" />
    <ModifyUserForm v-model="modifyUserVisible" :user-id="userId" @fetch="handleFetch" />
  </div>
</template>
<script>
  import { getUserList, modifyUser } from '@/api/user'
  import AddUserForm from './components/addUserForm'
  import ModifyUserForm from './components/modifyUser'
  export default {
    name: 'UserList',
    components: {
      AddUserForm,
      ModifyUserForm
    },
    data() {
      return {
        userList: [],
        addUserVisible: false,
        modifyUserVisible: false,
        userId: 0,
        total: 0,
        params: {
          page: 1,
          username: ''
        }
      }
    },
    created() {
      this.fetchUserList()
    },
    methods: {
      fetchUserList() {
        getUserList(this.params).then(res => {
          this.userList = res.results
          this.total = res.count
        })
      },
      handleUserStatusChange(obj) {
        modifyUser(obj.id, { is_active: obj.is_active }).then(() => {
          this.$message({
            message: `修改 ${obj.name} 的状态成功`,
            type: 'success'
          })
        })
      },
      handleFetch() {
        this.fetchUserList()
      },
      handleModify(obj) {
        this.userId = obj.id
        this.modifyUserVisible = true
      },
      handleChange(val) {
        this.params.page = val
        this.fetchUserList()
      },
      handleSearch() {
        this.params.page = 1
        this.fetchUserList()
      }
    }
  }
</script>

效果如下:可创建用户了

4.users/components/modifyUser.vue   ---用户修改功能

<template>
  <div class="modify-user-form">
    <el-dialog :visible.sync="visible" :title="title" @close="handleClose">
      <el-form ref="modifyUserForm" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="手机号:" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入手机号"/>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm">修改</el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script>
import { getUser, modifyUser } from '@/api/user'
export default {
  name: 'ModifyUser',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    userId: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      visible: false,
      userObj: null,
      form: {
        phone: ''
      },
      rules: {
        phone: [
          { required: true, message: '请输入联系电话', trigger: 'blur' }
        ]
      },
      uid: 0,
      title: ''
    }
  },
  watch: {
    value(val) {
      this.visible = val
    },
    userId(val) {
      if (val === 0) return
      this.uid = val
      this.fetchUser()
    }
  },
  methods: {
    handleClose() {
      this.visible = false
      this.$emit('input', false)
      this.userId = 0
      this.userObj = null
      this.resetForm()
      this.title = ''
    },
    resetForm() {
      this.$refs.modifyUserForm.resetFields()
      if (this.userId === 0) return
      if (this.userObj === null) return
      this.form.phone = this.userObj.phone
    },
    submitForm() {
      this.$refs.modifyUserForm.validate((valid) => {
        if (valid) {
          modifyUser(this.userId, this.form).then(() => {
            this.$message({
              message: `创建用户 ${this.userObj.name} 手机号成功`,
              type: 'success'
            })
            this.handleClose()
            this.$emit('fetch')
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    fetchUser() {
      getUser(this.uid).then(res => {
        this.title = `修改 ${res.name} 的信息`
        this.userObj = res
        this.form.phone = res.phone
      })
    }
  }
}
</script>

 

1

2

3

 

posted on 2020-07-15 21:38  单爆手  阅读(786)  评论(0)    收藏  举报