目录

一、文件上传

二、Models补充

三、Django总结

一、文件上传

1、通过form表单或者通过From类上传

  • views.py
from django.shortcuts import render,HttpResponse
from django import forms
from django.forms import fields


class UploadForm(forms.Form):
    user = fields.CharField()
    img = fields.FileField()

def upload(request):
    '''上传文件'''
    if request.method == 'GET':
        return render(request,'upload.html')
    else:
        '''
        # 基于Form也可以上传,这里还做了验证
        obj = UploadForm(request.POST,request.FILES)
        if obj.is_valid():
            user = obj.cleaned_data['user']
            img = obj.cleaned_data['img']
        '''
        #img是对象,封装了文件大小、名称、内容。。。
        img = request.FILES.get('img')
        print(img.name)
        print(img.size)
        #将上传文件写入本地
        f = open(img.name,'wb')
        #上传是一点一点的,所以不能一下子拿到全部,需要循环
        for line in img.chunks():
            f.write(line)
        f.close()
        return HttpResponse('上传成功')
  • upload.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #c1{
            position: absolute;
            top:0;
            left:0;
            opacity: 0;
        }
        #c2{
            background-color: dodgerblue;
            border: 1px solid lightblue;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <form action="/upload.html" method="POST" enctype="multipart/form-data">
        <input type="text" name="user"/>
        {#修改上传按钮的样式,其实就是把按钮隐藏,上面覆盖一个新的按钮#}
        <div style="position: relative;">
            <a id="c2">新上传</a>
            <input type="file" name="img" id="c1"/>
        </div>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>

2、jQuery ajax和原生的ajax上传

  • 两者都用到了同一个类FormData()来封装用户提交的数据,本质上ajax和原生ajax原理一样,因为底层都是用的类XMLHttpRequest;

  • 但是不是每一个浏览器都有FormData(),有一些低版本的IE可能不支持;所以如果考虑兼容性的问题,尽量用iframe + form的形式;

  • views.py

#将文件保存到本地,对下面两个方式都适用
def ajax1(request):
    ret = {'status':True,'msg':'666'}
    import json
    data = request.FILES.get('k')
    f = open(data.name,'wb')
    for line in data:
        f.write(line)
    f.close()
    return HttpResponse(json.dumps(ret))
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load staticfiles %}
    <style>
        .btn{
            display: inline-block;
            padding: 5px 10px;
            background-color: #2aabd2;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body> 
    <h3>Ajax上传文件</h3>
    <input type="file" id="img"/>
    <a class="btn" onclick="ajaxSubmit6();">ajax上传</a>
    <a class="btn" onclick="ajaxSubmit7();">原生ajax上传</a>
    <script src="{% static 'js/jquery-1.12.4.js' %}"></script>
    <script>
        //上传文件
        //通过FormData
        function ajaxSubmit6() {
            //得到img标签上传的文件
            var f = document.getElementById('img').files[0];
            var data = new FormData();
            data.append('k',f);
            $.ajax({
                url:'/ajax1.html',
                type:'POST',
                data:data,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success:function (arg) {
                    console.log(arg);
                }
            })
        }
        //通过原生ajax上传
        function ajaxSubmit7() {
            var f = document.getElementById('img').files[0];
            var data = new FormData();
            data.append('k',f);
            var xhr = new XMLHttpRequest();
            xhr.open('POST','/ajax1.html');
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    console.log(xhr.responseText);
                }
            };
            xhr.send(data);
        }
    </script>
</body>
</html>

3、iframe + form 上传文件

  • iframe默认是不显示的;

  • views.py

def ajax1(request):
    ret = {'status':True,'msg':'666'}
    import json
    #iframe + form 上传文件
    data = request.FILES.get('img3')
    f = open(data.name,'wb')
    for line in data:
        f.write(line)
    f.close()
    return HttpResponse(json.dumps(ret))
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load staticfiles %}
    <style>
        .btn{
            display: inline-block;
            padding: 5px 10px;
            background-color: #2aabd2;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h2>5.基于iframe+Form上传文件</h2>
    <div>
        <iframe id="iframe3" name="frame3" style="display: none;" ></iframe>
        <form id="fm3" action="/ajax1.html" method="POST" target="frame3" enctype="multipart/form-data">
            <input type="file" name="img3"/>
            <a onclick="ajaxSubmit8();" class="btn">iframe上传</a>
        </form>
    </div>

    <script src="{% static 'js/jquery-1.12.4.js' %}"></script>
    <script>
        //iframe+form上传
        function ajaxSubmit8() {
            document.getElementById('iframe3').onload = reloadIframe3;
            document.getElementById('fm3').submit();
        }
      //相当于回调函数,通过判断后台返回的消息来进行下一步操作,只不过后台返回的内容在iframe中
        function reloadIframe3() {
            var content = this.contentWindow.document.body.innerText;
            var ret = JSON.parse(content);
            if(ret.status){
                alert('000');
            }
        }
    </script>
</body>
</html>

4、上传图片时在页面上预览

  • views.py
from django.shortcuts import render,HttpResponse
import json
import os
import uuid

def upload(request):
    return render(request,'upload.html')

def upload_img(request):
    ret = {'status': True,'data':None, 'msg': None}
    obj = request.FILES.get('img')
    #为避免文件名重复被覆盖,文件名加个前缀
    nid = str(uuid.uuid4())
    file_path = os.path.join('static',nid+obj.name)
    f = open(file_path, 'wb')
    for line in obj.chunks():
        f.write(line)
    f.close()
    ret['data'] = file_path
    return HttpResponse(json.dumps(ret))
  • upload.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load staticfiles %}
    <style>
        .btn{
            background-color: #2aabd2;
            color: white;
            cursor: pointer;
            padding: 4px 2px;
        }
        .upload{
            position: absolute;
            top:0;
            left:0;
            opacity: 0;
        }
    </style>
</head>
<body>
    <h2>基于iframe+Form上传文件</h2>
    <div>
        <iframe id="iframe" name="fram" style="display: none;" ></iframe>
        <form id="fm" action="/upload_img.html" method="POST" target="fram" enctype="multipart/form-data">
            <div style="position: relative">
                <a class="btn">iframe上传</a>
                <input type="file" name="img" onchange="uploadFile();" class="upload"/>
            </div>
        </form>
        <h3>预览</h3>
        <div id = 'preview'>
        </div>
    </div>
    <script src="{% static 'js/jquery-1.12.4.js' %}"></script>
    <script>
        function uploadFile() {
            document.getElementById('iframe').onload = reloadIframe;
            document.getElementById('fm').submit();
        }
        function reloadIframe() {
            var content = this.contentWindow.document.body.innerText;
            var obj = JSON.parse(content);
            //生成一个img标签
            var tag = document.createElement('img');
            tag.src = obj.data;
            //先清空上一次的照片,再添加新的照片路径
            $('#preview').empty().append(tag);
        }
    </script>
</body>
</html>

二、Models补充

1、字段补充

    AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 0 ~ 32767
    IntegerField(Field)
        - 整数列(有符号的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型,小数位越多,约不精确,小数建议使用下面字段

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型
View Code

相关文章: