• django文件的上传与下载


    一、通过modelForm文件上传

     1、设置setting.py文件

      

    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')  # 即项目路径下的media文件夹,没有则自动创建
    MEDIA_URL = '/media/'  # 这个是在浏览器上访问该上传文件的url的前缀
    

     2、做model

    class ShenSu(models.Model):
        def upload_to(instance, filename):
            return '{0}/{1}/{2}'.format(instance.resultSum.kaohe_period.id, instance.resultSum.beikao_user.id,filename)
    resultSum = models.OneToOneField(ResultSum, null=True, verbose_name="原考核结果",on_delete=models.SET_NULL) old_result = models.DecimalField(default=0, max_digits=4, decimal_places=1, null=True, blank=True,verbose_name='原考核得分') new_result = models.DecimalField(default=0, max_digits=4, decimal_places=1, null=True, blank=True,verbose_name='申诉后得分') memo = models.TextField(max_length=200,verbose_name="备注说明") file1 = models.FileField(upload_to=upload_to, null=True, blank=True) file2 = models.FileField(upload_to=upload_to, null=True, blank=True) def __str__(self): return self def delete(self, *args, **kwargs): self.file1.delete() self.file2.delete() super().delete(*args, **kwargs)

    class ShenSu(models.Model):

    def upload_to(instance, filename):
    #upload_to =/path/ 是绝对路径 #upload_to =path/ 是相对路径
    return '{0}/{1}/{2}'.format(instance.resultSum.kaohe_period.id, instance.resultSum.beikao_user.id,filename)

    resultSum = models.OneToOneField(ResultSum, null=True, verbose_name="原考核结果",on_delete=models.SET_NULL)
    old_result = models.DecimalField(default=0, max_digits=4, decimal_places=1, null=True, blank=True,
    verbose_name='原考核得分')
    new_result = models.DecimalField(default=0, max_digits=4, decimal_places=1, null=True, blank=True,
    verbose_name='申诉后得分')
    memo = models.TextField(max_length=200,verbose_name="备注说明")
    file1 = models.FileField(upload_to=upload_to, null=True, blank=True)
    file2 = models.FileField(upload_to=upload_to, null=True, blank=True)

    def __str__(self):
    return self

    def delete(self, *args, **kwargs):
    self.file1.delete()
    self.file2.delete()
    super().delete(*args, **kwargs)

    3、在总project的url.py里面添加

    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    

      注意要在总工程, 不能在下面subapp目录中。

    4、update.html form

    <form action='.' method='POST' enctype="multipart/form-data">
    	{% csrf_token %}
        {{ form|crispy }}
        <input type='submit' class="btn btn-primary" value='保存' />
    </form>
    

      

    5、view.py


    def post(self, request, *args, **kwargs): # POST method
        form = ShenSuForm(request.POST, request.FILES) #如果是新录入
           form = ShenSuForm(request.POST,request.FILES, instance=obj) #如果是update操作,取得model的instance,结合页面post的数据,更新db

           if form.is_valid():
               form.save()
               messages.success(request, '操作成功!')
          return redirect(reverse('{}:{}List'.format(APPNAME,MYTABLE.__name__)))

      

    6、update上传成功

    录入页面:

    查看页面

    上面页面,对应的代码片段:

    		{% for obj in object_list %}
    			<tr>
    				<td>{{ obj.resultSum.kaohe_period }}</td>
    				<td>{{ obj.resultSum.beikao_user }}</td>
    				<td>{{ obj.old_result }}</td>
    				<td>{{ obj.new_result }}</td>
    				<td>
    					{% if obj.file1 %}
    						<a href="{{ obj.file1.url }}" class="btn btn-primary btn-sm" target="_blank">
    						  Download PDF
    						</a>
    					{% endif %}
    				</td>
    

       

     问题:

     点击download pdf  , 直接打开的地址是:http://127.0.0.1:8000/media/20203/150001/175206vf5t8d4r8ooo5obt.pdf

    也就是说,没有任何权限控制,开放了media目录, 这是debug模式才允许的。

    所以,上述,只实现了upload,接下来看如何实现真正的download

    二、正式环境中(非debug)模式的下载

    1、使用 django-downloadview app, 否则的话需要自己open(file) ,write写入等,很麻烦。

     pip install django-downloadview

    2、编写download view

      model还是上面的ShenSu表,里面可以上传2个附件,file1 ,file2 

     下面2个view是分别下载file1和file2的。view中可以控制权限。

    def download1(request, id):
        from django_downloadview import ObjectDownloadView
    #根据表名称, 文件字段的名称,定义download view filex = ObjectDownloadView.as_view(model=ShenSu, file_field='file1', attachment=False)
    #根据表的instance id ,下载。 return filex(request, pk=id) def download2(request, id): from django_downloadview import ObjectDownloadView filex = ObjectDownloadView.as_view(model=ShenSu, file_field='file2', attachment=False) return filex(request, pk=id)

    3、编写URL

        path('download1/<int:id>/file1/', download1, name='download1'),
        path('download2/<int:id>/file2/', download2, name='download2'),
    

     4、前端

    <td>
    {% if obj.file1 %}
    <a href="{% url 'kaohe:download1' obj.id %}" target="_blank"> 下载</a>
    {% endif %}

    </td>
    <td>
    {% if obj.file2 %}
    <a href="{% url 'kaohe:download2' obj.id %}" target="_blank"> 下载</a>
       {% endif %}
    </td>

    5、效果

      点击下载的连接 ,直接可以打开文件内容 你可以看到,url 是 “.....download1/5/file1” , 5是传入的参数,是model的primary key。 download1决定了下载file1文件, download2决定下载file2字段

  • 相关阅读:
    Nginx系列教材 (四)- 和Tomcat进行动静分离整合
    Nginx系列教材 (三)- 反响代理Tomcat
    Nginx系列教材 (二)- 为Nginx准备的多个Tomcat
    Nginx系列教材 (一)- 教程
    Redis系列教材 (六)- Client
    Redis系列教材 (五)- Spring Data Redis 使用例子
    Redis系列教材 (四)- Jedis 教程
    Redis系列教材 (三)- 常见命令
    jq实时监听input值变化
    rem适配的代码
  • 原文地址:https://www.cnblogs.com/lxgbky/p/14475028.html
Copyright © 2020-2023  润新知