1

I'm kinda new to python and I'm creating a website that users can buy Hi-Res images and now I'm looking for a way to let user to download the images that they've bought, from the Django model, Here is my pic model:

class Pic(models.Model):
    name = models.CharField(max_length = 60, blank = False)
    description_sizes = models.TextField(blank = False, name = 'des_sizes', max_length = 360)
    captured_time = models.DateField(blank = False)
    price = models.IntegerField(blank = False)
    preview = models.ImageField(upload_to = f'static/post/preview/', null = False, blank = False)
    tags = models.CharField(max_length = 1000, blank = False)
    image_files = models.FileField(upload_to ='posts/ogFiles', null = True, blank = False)

My views.py :

def singlePostView(request, pic_id = None):
    pic = Pic.objects.get(id = pic_id)
    print(pic)

    context = {
    'pic':pic,
    }
    return render(request,"post/single_post_view.html", context)
  

I'm looking for way to make a button or link to download the image_file from pic model in the single view, and I've been searching for this for couple of days now and I've just came across these : xsendfile module

or using serve like this :

 <a  href="/project/download"> Download Document </a>

and in urls.py:

url(r'^download/(?P<path>.*)$', serve, {'document root': settings.MEDIA_ROOT}),

well for xsendfile module it's not really an efficient way bc

  • was originally designed for Apache 2 & 2.2.
  • is not a standard Apache module
  • hasn't been maintained since 2011.

and for the serve because it's not a protected url user can download other files in other paths.

is there any alternative solution for downloading from Django model??

  • There are a few elements to consider. First, where are the image files hosted? Are they on the same server where the Python code is running? And second, how is the purchase / transaction being handled -- do you have Python code for that too? There needs to be some logic to make sure that the current user is allowed to download the image. Are you handling that right now? – Greg Sadetsky Sep 11 '21 at 19:41
  • @GregSadetsky yeah Image files are hosted on the same server (with Python web app) , well I'm using an API for purchase and it returns boolean value weather the transaction is done or not, and then if it's done I'm changing the **Is_paid** value in my context and in template it goes sth like this: `{% if Is_paid%} active download link {%else%} inactive download link {%endif%} ` – Novartis Nk Sep 12 '21 at 07:40
  • Ok, it would help to see all of the views that you have. Do you get `Is_paid` in a view (after the user submits a payment) and then set it on the session? Do you store the fact that a user has paid in the database, or is that value only held in memory? I think that one simple (even though not ideal) way forward would be to use the session object, and note that the user has purchased an image on their session. And then, to create a new view that checks this session value and then responds with the file content. – Greg Sadetsky Sep 13 '21 at 13:27

2 Answers2

1

You can add "download" attribute inside your tag to download files.

<a  href="/project/download" download> Download Document </a>

https://www.w3schools.com/tags/att_a_download.asp

source: https://stackoverflow.com/a/57803641/10178508

Ismayil Ibrahimov
  • 440
  • 1
  • 7
  • 11
  • Ik this one, as I said it's not a safe way bc I want to have some restrictions over what kind of files and pic user can take from the server, by doing this user can pick up any kind of pics or files that they want from the file of the server by simply changing the url in inspect mode – Novartis Nk Sep 12 '21 at 12:14
  • you can generate complex image name at Pic model for image_files field, and then use {% if Is_paid%} Download Document {%else%} Download Document {%endif%} – Ismayil Ibrahimov Sep 12 '21 at 13:00
  • actually this is not true way doing this, if you don't want user can see url after payment you can use post method, and after form submitted automatically download file from server – Ismayil Ibrahimov Sep 12 '21 at 13:20
  • yeah exactly but the problem is user can only download it after the payment not at anytime he/her wants, if user wants to download it again it's not possible this way – Novartis Nk Sep 12 '21 at 14:42
1

You need to tell the browser to treat the response as a file attachment.

According to Django document link This is how you can do -

response = HttpResponse(my_data, headers={'Content-Type': 'image/jpeg','Content- 
           Disposition': 'attachment; filename="foo.jpeg"'}).

Read about the Content-Disposition header.

Ranu Vijay
  • 1,137
  • 9
  • 18
  • Thank you so much, I tried this in a view and set some restrictions for user ( if user is authenticated or not and if purchase flag is up or not ) and it's working like a charm and user can't download other files from server :) – Novartis Nk Sep 29 '21 at 15:21