Django、Vue前后端分离保存图片(使用ImageField字段)

models.py
from django.db import models

import uuid
import os

def user_directory_path(instance, filename):
    print(instance.btitle)
    return os.path.join( "upload", filename)

class BookInfo(models.Model):
    btitle = models.CharField(max_length=50, verbose_name="标题")
    bcontent = models.TextField(verbose_name="内容")
    bread = models.IntegerField(verbose_name="阅读量", default=0)
    bprice = models.DecimalField(verbose_name="价格", max_digits=6, decimal_places=2, default=20)
    bpub_date = models.DateTimeField(verbose_name="发布日期", auto_now_add=True)
    is_delete = models.BooleanField(verbose_name="删除标记", default=False)

    image = models.ImageField(upload_to=user_directory_path, verbose_name="图片")

    def __str__(self):
        return self.btitle

    class Meta:
        verbose_name = "图书信息"
        verbose_name_plural = verbose_name
  

class User(models.Model):
    '''用户表'''
    name=models.CharField(verbose_name='用户名字',max_length=50,primary_key=True,db_index=True)
    tag=models.CharField(verbose_name='标签',max_length=50,db_index=True,default='')
    create_time=models.CharField(verbose_name='创建时间戳',max_length=50,default=0)
    class Meta:
        managed=True
        verbose_name_plural='用户表'
    def __str__(self):
        return self.name
admin.py
from django.contrib import admin
from myapp import models
# Register your models here.


admin.site.register(models.BookInfo)
admin.site.register(models.User)

serializer.py
import imp
from rest_framework import serializers
from myapp.models import *

class UserSerializer(serializers.Serializer):
    name = serializers.CharField()
    tag = serializers.CharField()
    create_time = serializers.CharField()

    def create(self,validated_data):    # validated_data是自带的参数,序列化器帮忙传的,就是验证完的数据
        # 这里的写法和视图中没什么区别,只是拿到序列化器中来写了,需要在上面导入模型类 import User
        # 本来validated_data是{'name':'ybc','age':18}, **打散,之后的validated_data是 nam=ybc, age=18
        result = User.objects.create(**validated_data)
        # 把添加的数据返回给函数调用处
        return result
    
    def update(self,instance,validated_data):
        instance.name=validated_data.get('name')
        instance.tag=validated_data.get('tag')
        instance.create_time=validated_data.get('create_time')
        instance.save() # 模型的保存
        return instance


class BookInfoSerializer(serializers.Serializer):
    """书籍的序列化器"""
    # 序列化器中的字段可以比模型类多,也可以比模型类少
    id = serializers.IntegerField(label="ID", read_only=True)
    btitle = serializers.CharField(label="标题", max_length=50)
    bcontent = serializers.CharField(label="内容", required=True)
    bread = serializers.IntegerField(label="阅读量", required=False)
    bprice = serializers.DecimalField(label="价格", max_digits=6, decimal_places=2, required=False)
    bpub_date = serializers.DateTimeField(label="发布日期", required=False)
    image = serializers.ImageField(label="图片", required=False)
    

# class UserSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = User
#         fields = '__all__'
    
#     def create(self,validated_data):    # validated_data是自带的参数,序列化器帮忙传的,就是验证完的数据
#         # 这里的写法和视图中没什么区别,只是拿到序列化器中来写了,需要在上面导入模型类 import User
#         # 本来validated_data是{'name':'ybc','age':18}, **打散,之后的validated_data是 nam=ybc, age=18
#         result = User.objects.create(**validated_data)
#         # 把添加的数据返回给函数调用处
#         return result
    
#     def update(self,instance,validated_data):
#         instance.name=validated_data.get('name')
#         instance.tag=validated_data.get('tag')
#         instance.save() # 模型的保存
#         return instance
    

views.py
from email import header
from lib2to3.pgen2 import driver
from django.db.models import Q, query
from requests import head
from myapp.models import *
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import pagination                #分页
from myapp.serializer import *
import json
# Create your views here.


class HelloWorldViewSet(GenericViewSet):
    queryset=''

    @action(detail=False,methods=['GET'])
    def front(self,request):
        all_data = User.objects.all()
        # single_res = UserSerializer(instance=all_data.first())
        # print(single_res.data)
        self.queryset = UserSerializer(all_data,many=True).data

        # res={'single':single_res,'all':all_res}
        return Response(self.queryset)
    
    @action(detail=False,methods=['GET'])
    def reverse_create(self,request):
        data=[
                {
                    "name": "李四2",
                    "tag": "老师",
                    "create_time": "555555555555"
                },
                {
                    "name": "王五2",
                    "tag": "学生",
                    "create_time": "44444444444"
                }
        ]
        
        serobj = UserSerializer(data=data,many=True) # 反序列化用data,序列化用instance,可以不写,默认传的就是instance
        
        serobj.is_valid() # 验证数据
        self.queryset=serobj.validated_data

        # 执行数据库操作,save源码会根据实例化序列器对象中是否传递instance而自动调用的create或者update方法,如果没有传递,就是create方法,此处没传,所以是create
        serobj.save()
        print(serobj.validated_data) # 可以拿到通过的数据
        print(serobj.errors) # 可以拿到错误的信息

        return Response(self.queryset)
    
    @action(detail=False,methods=['GET'])
    def reverse_update(self,request):
        old_data=User.objects.get(name='张三66')

        # res=UserSerializer(instance=old_data).data

        new_data={
                    "name": "张三66",
                    "tag": "老师666",
                    "create_time": "666"
                }
        
        
        # 执行数据库操作,save源码会根据实例化序列器对象中是否传递instance而自动调用的create或者update方法,如果没有传递,就是create方法,此处没传,所以是create
        serobj = UserSerializer(instance=old_data,data=new_data) 

        if serobj.is_valid(): # 验证数据
            #执行数据库操作【自动调用的create或者update方法】,此处是update
            serobj.save()

        print(serobj.validated_data) # 可以拿到通过的数据
        print(serobj.errors) # 可以拿到错误的信息

        
        

        return Response(serobj.validated_data)

    


views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import action

from .serializers import BookInfoSerializer
from .models import BookInfo

from Py_Redis import settings


class BookInfoList(GenericViewSet):
    """图书列表类视图"""
    serializer_class=''
    
    @action(detail=False,methods=['GET'])
    def get(self, request):
        books = BookInfo.objects.all()
        serializer  = BookInfoSerializer(instance=books, many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    @action(detail=False,methods=['POST'])
    def post(self, request):
        r=request.data.get('file')
        print(r)
        BookInfo.objects.create(
            btitle = '1',
            bcontent = '1',
            bread = '1',
            bprice = '1',
            is_delete = '1',

            image = r

        )
        return Response({'code':200})
    
    @action(detail=False,methods=['GET'])
    def save_img(self,request):
        print(1211)
        return Response({'code':200})  
HelloWorld.vue
<template>
  <div id="helloworld">
    {{test_ajxs}}
    <el-upload
          name="upfile"
          width="30%"
          action="http://127.0.0.1:8000/books/post/"
          ref="upload"
          :on-change="handleChange"
          :file-list="fileList"
          :auto-upload="false"   
        >
        <el-button slot="trigger" size="small" type="primary" >选取文件</el-button>
        <el-button id="up_file"  size="small" type="success" @click="run_up" >点击上传</el-button>
    </el-upload>
    <div v-for="value,index in data" :key="index">
      {{dateFormat(value.bpub_date)}}
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      fileList:[],
      data:[]
    }
  },
  methods:{
    //时间格式转换
    dateFormat: function (time) {
      var date = new Date(time);
      var year = date.getFullYear();
      /* 在日期格式中,月份是从0开始的,因此要加0
       * 使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
       * */
      var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
      var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
      var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
      var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
      var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
      // 拼接
      return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
    },

    run_up(){
        for (let i = 0; i < this.fileList.length; i++) {

            this.upDataFile(this.fileList[i].raw,);
        }
        // this.$refs.upload.submit()
    },

    upDataFile(fileData) {
        console.log(fileData)
        var formdata = new FormData()
        formdata.append("file", fileData)
        this.axios({
            url:'/api/books/post/',
            method:'post',
            data:formdata, //我们传formdata会占用整个传参对象
            headers:{"Content-Type": "multipart/form-data"}
            }).then(res=>{
                this.fileList=[]
            })
    },

    handleChange(files, fileList) {
        this.fileList.push(files)
    },
  },
  computed:{
    test_ajxs(){
      // var formdata = new FormData()
      // formdata.append("file", 'fileData')
      // this.axios({
      //       url:'/api/books/post/',
      //       method:'post',
      //       data:formdata, //我们传formdata会占用整个传参对象
      //       headers:{"Content-Type": "multipart/form-data"}
      //       }).then(res=>{
      //           console.log(res)
      //       })
      
      this.axios({
            url:'/api/books/get/',
            method:'get',
            }).then(res=>{
              if(res.status==200){
                  this.data=res.data
                }else{
                  alert('111')
                }
            })
    }
  }
}
</script>
setting.py
"""
Django settings for Py_Redis project.

Generated by 'django-admin startproject' using Django 3.2.5.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-00c^62y*p3a$soc#%dgjv7%9z@r5nxedu6a3as0@i0vv!$)z9%'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'myapp',
    'corsheaders',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'corsheaders.middleware.CorsMiddleware',   
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'Py_Redis.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 = 'Py_Redis.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'py_redis',
        'USER':'root',
        'PASSWORD':'pert',
        'HOST':'localhost',
        'PORT':'3306'
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

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',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'
UPLOAD_FILE= os.path.join(BASE_DIR,'upload')



# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'


# 跨域增加忽略,放在最下面
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True


CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:8000',
)


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',
)
index.js
proxyTable: {
      '/api':{
        target:'http://127.0.0.1:8000/',   
        changeOrigin:true,
        pathRewrite:{
            '^/api':''
            }
        }
    },
urls.py
from django.contrib import admin
from django.urls import path,include

from django.views.static import serve
from Py_Redis import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('myapp.urls')),
    path('upload/<path>',serve,{'document_root':settings.UPLOAD_FILE})
]


myapp/urls.py
from django.urls import path, re_path

from rest_framework.routers import DefaultRouter

from . import views



router = DefaultRouter()
router.register('books',views.BookInfoList,basename="booklist")

urlpatterns = router.urls
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

import axios from 'axios'
Vue.prototype.axios=axios

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';


Vue.config.productionTip = false

Vue.use(ElementUI);

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值