zoukankan      html  css  js  c++  java
  • django 上传文件

    最近在做一个管理问句的平台,需要上传一些问句,就想用django的upload模块来做,遇到一些问题,记录一下。

    就拿测试用的demo来做例子吧:

    第一:因为django默认的文件是存储在media下面的,所以需要现在settings.py里面把media定义一下

    CUR_DIR=os.path.dirname(__file__)
    MEDIA_ROOT = os.path.join(CUR_DIR,'media/')
    
    # URL that handles the media served from MEDIA_ROOT. Make sure to use a
    # trailing slash.
    # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
    MEDIA_URL = '/media/'

    然后就是写forms和models.

    #forms.py
    from django import forms
    from django.forms.widgets import *
    from blogapp.validate import * 
    
    class UpLoadPicForm(forms.Form):
        title=forms.CharField(max_length=100)
        pic=forms.FileField(validators=[validate_fize])
    
    #models.py
    class Pic(models.Model):
        #这里的保存目录就是/mdeia.documents/%Y
        pic=models.FileField(upload_to='documents/%Y')
    
    class PicGallery(models.Model):
        picid=models.IntegerField(primary_key=True)
        pic=models.ManyToManyField(Pic)

    OK,都定义好了,然后就是把views.py补上

    def uploadPic(request):
        if request.method=="POST":
            form=UpLoadPicForm(request.POST,request.FILES)
            if form.is_valid():
                storePic(request.FILES)
                return HttpResponse("success")
        else:
            form=UpLoadPicForm()
        return render_to_response('upload.html',{"form":form},context_instance=RequestContext(request))
    
    def storePic(fileobj):
        newdoc=Pic(pic=fileobj["pic"])
        newdoc.save()

    然后是超简单的模板页面

    <form enctype="multipart/form-data" method='post',action='/upload/'>
        {% csrf_token %}
        <p>{{ form.non_field_errors }}</p>
        <p>
        {{form.title.errors}}
        {{form.title.label_tag}}
        {{form.title}}
        </p>
        <p>
        {{ form.pic.errors }} 
        {{form.pic}}
    {{ form.pic.errors }} 
        {{form.pic}}
    
        </p>
        <input type="submit",value="提交">
    </form>

    这样就实现了上传文件,过程很简单,然后着重说下我遇到过的问题.

    第一:UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value.  This is usually caused by not using RequestContext.

    这个错误发生的原因在与

    return render_to_response('upload.html',{"form":form},context_instance=RequestContext(request))

    这个里面忘记添加了context_instance=RequestContext(request),一开始不知道为什么,后来才发现django的说明文档里面有这么一句话:

    If you are using generic views or contrib apps, you are covered already, since these apps use RequestContext throughout

    而我这里的upload不属于contrib apps也不属于通用视图,所以需要手动添加RequestContext

    第二:instance is on database "None", value is on database "default"

    这个问题很粗心,发生的原因是这样的,我本来是想一个图库,就是PicGallery

    于是我的storePic方法就变成了:

    def storePic(fileobj):
        newdoc=Pic(pic=filobj["pic"])
        newdoc.save()
        picgallery=PicGallery(1)
        picgallery.pic.add(newdoc)
        picgallery.save()

    问题就在于我这里的picgallery一开始就是没这个query结果的,所以当我add的时候就出错了,应该先picgallery.save(),然后再是add()

    第三:object has no attribute _state

    这个也是很粗心,我本来是想再扩展下Pic这个模型的,然后就变成

    class Pic(models.Model):
        pic=models.FileField(upload_to='documents/%Y'def __init__(self,*args,**kargs):
            '''
    问题就在于我这里init没有任何操作,也没有去super,所以出错了,
            '''
              pass        

    第四:DjangoUnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 77: invalid start byte.

    这个问题是我想尝试下多个文件上传的时候出现的。

    def storePic(fileobj):
        print fileobj["pic"]
      
    ''' 本来是这样,但是出现了错误 for pic in fileobj["pic"]: 后来通过getlist来获取上传的多个文件对象,才可以了 ''' for pic in fileobj.getlist('pic'): newdoc=Pic(pic=pic) newdoc.save()

    PS:另外是自己学的一些,因为以前如果想自定义判断一个form数据是否有效的函数,都是在外部定义,比如在forms.is_valid()之后再调用自己的验证函数,今天也刚好尝试一下在form里面添加validate

    比如我要判断文件大小是不是大于8M:

    #validate.py
    from django.core.exceptions import ValidationError
    def validate_fize(value):
        if value.size>8*1024:
            raise ValidationError(u'sorry ,the size is too large',code='_invalid') 

    然后调用就是在定义forms的时候

    class UpLoadPicForm(forms.Form):
        title=forms.CharField(max_length=100)
        pic=forms.FileField(validators=[validate_fize])

    即可,具体运行结果就是:

    另外记录一个判断图片类型的函数:
    def get_pic_type(picobj):
        filetype=None
        data=picobj.read(10).encode("hex")
        if data.startwith("ffd8ffe0"):
            filetype="jpg"
        elif data.startwith("474946"):
            filetype="gif"
        elif data.startwith("424d"):
            filetype="bmp"
        elif data.startswith('89504e470d0a1a0a'):
            filetype="png"
        return filetype
     
    就算不在校园,也要保持饥渴,学到老,活到老嘛 我是一个小QA,我为自己代言!!!!!!!!!!!!!
  • 相关阅读:
    缓冲字符流 java.io.BufferedWriter ,java.io.BufferedReader,缓冲字符输出流:PrintWriter
    转换流读写操作 java.io.OutputStreamWriter ,java.io.InputStreamReader
    对象流,它们是一对高级流,负责即将java对象与字节之间在读写的过程中进行转换。 * java.io.ObjectOutputStream * java.io.ObjectInputStream
    flush() 缓冲输出流的缓冲区问题
    使用文件流与使用缓冲流完成文件的复制操作性能对比,文件流 FileInputStream FileOutputStream 缓冲流: BufferedInputStream BufferedOutputStream
    RandomAccessFile()实现用户注册功能, 新增,查询,更新
    RandomAccessFile实现简易记事本工具操作
    对比两种方式复制文件的效率
    File 删除给定的文件或目录
    RandomAccessFile(),读写文件数据的API,以及复制文件操作
  • 原文地址:https://www.cnblogs.com/xiamuyouren/p/3275796.html
Copyright © 2011-2022 走看看