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字段

原文地址:https://www.cnblogs.com/lxgbky/p/14475028.html