Need a minimal Django file download example - django

I'm facing difficulty to download (the already uploaded) files as I am a newbie in django. Also I could not find a way to do that (the uploaded files are of different formats). May someone post a minimal but complete (Model, View, Template) example code to do so?

So if you alredy have model like:
class MyFile(models.Model):
file_field = models.FileField()
In your view add your uploaded file in template context like:
{'myfile': MyFile.objects.get(id=1)}
In your template just use <a> tag with:
href="{{ myfile.file_field.url }}"

Related

Django: a custom template tag to convert links inside of a TextField and change the hyperlink text

The scenario is that there are some dynamic texts on some templates, that will contain hyperlinks.
For this, I have a SiteDataKeyValue model, in which the dynamic texts for different parts of the template are inputted. This is the model:
class SiteDataKeyValue(models.Model):
key = models.CharField(
max_length=200, verbose_name="نام متن مورد نظر", unique=True
)
value = models.TextField(verbose_name="متن")
def __str__(self):
return self.key
A solution that I've found already, is Django urlize template tag. As mentioned in the docs, this tag converts texts like https://www.google.com to www.google.com, which is nice but not what I'd like to achieve. I want to be able to change the hyperlink text, so the output would be something like: Click Here!.
I searched for a bit, came across modules like bleach, which is a fine module, but I couldn't find the answer I was looking for (I skimmed through the docs and there was nothing about the hyperlink text).
Also I saw a comment somewhere telling that this could be achieved by writing a custom Django template tag, but although I tried to do this regarding the custom template filters docs, I didn't have a clue to how to achieve this.
I'm not asking for the code, although it would be really appreciated if you provide instructions for writing this custom template tag, or better, if you could point me to something like this that is already out there.
First of all you can extend urlize tag like the answer in this
or you can change the main code which you can find it in django.utils.html and override its url variable to change it.
But I think the best method is extending the urlize tag
like this:
{% text | urlize | change_a_text_filter:{{ dome_new_a_text }} %}
then you can scrape the text and use regex to find >sample-text</a> then you can change it to the argument that defines in your tag
from django import template
register = template.Library()
#register.simple_tag
def change_a_text_filter(format_string, arg):
# find the url that made in urlize with regex
# change it with arg
# return the result
I was on a completely wrong road to solve this problem. I was trying to urlize a link from TextField, but didn't consider the fact that I only needed to implement html code as Visit link.com! in the TextField, and then use safe template tag to render html directly as below:
{{ text.value|safe }}
So in this solution, there is no need to urlize, and of course there is no need to extend this tag neither.
NOTE: As commented by #rahimz (link to comment) I understand that there are safety concerns regarding safe tag, So I should emphasize that only me and a company-trusted admin will have access to admin panel and there is no worries that this admin will send malicious code through this TextField.

Cannot link to static files with Hugo

I have this in config.toml:
baseURL = "https://my-username.github.io/blog/"
and there is a static file at static/img/foo.png.
Now, in content/posts/bar.md, I have the following content:
---
title: "Bar"
---
![foo](img/foo.png)
The picture isn't showing after I started the hugo server, so I inspected elements, and found out that Hugo generated the following URL for it:
http://localhost:1313/blog/posts/bar/img/hireme.png
This is not what I expect; it should be
http://localhost:1313/blog/img/hireme.png
When I use ![foo](/blog/img/foo.png), the picture is displayed correctly, but this is quite strange: /blog/ is part of baseURL, why do I need to type it again?
I think you should use <base> tag to make baseURL for static files.
Add the <base> tag into <head>:
<base href="{{ .Site.BaseURL }}">
And then you can insert image in post like this:
![Foo image](img/foo.jpg)
References:
https://www.w3schools.com/tags/tag_base.asp
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
In a simple setup where your site lives in the domain's root, a absolute reference to the image would be a standard practice. However, in your case where the site is nested, a more crafty solution is necessary.
I suggest using a shortcode to solve your dilemma. Just simply create a shortcode that takes in a resource file path and spits out the desired absolute path every time. The advantage to this approach is flexibility for future resource relocation to a cdn for example.
Your markdown code will be something like this:
![foo]({{< resource url="img/foo.png" >}})
Your shortcode template will be something like this:
{{ .Site.BaseURL }}{{ .Get "url" }}
Create a file named 'resource.html' in 'layouts/shortcodes/' folder, and drop in the shortcode template code above.
So when you decide you want to switch to a cdn you could easily do this:
://cdn.example.com/{{ .Get "url" }}

Wagtail mock images show as broken in admin but visible on template

I have a demo Wagtail website. A site is generated via a Cookiecutter. To populate the CMS with initial content I have added a load_initial_data command that can be run once Wagtail is installed. This populates text content from a fixtures JSON file, and moves images from the fixtures folder to the Wagtail site's media_root folder. The code looks like:
# load_initial_data.py
import os, shutil
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.management import call_command
class Command(BaseCommand):
def handle(self, **options):
fixtures_dir = os.path.join(settings.PROJECT_DIR, 'fixtures')
fixture_file = os.path.join(fixtures_dir, 'db.json')
image_src_dir = os.path.join(fixtures_dir, 'images')
image_dest_dir = os.path.join(settings.MEDIA_ROOT, 'original_images')
call_command('loaddata', fixture_file, verbosity=0)
if not os.path.isdir(image_dest_dir):
os.makedirs(image_dest_dir)
for filename in os.listdir(image_src_dir):
shutil.copy(os.path.join(image_src_dir, filename), image_dest_dir)
This works to the extent that the images are copied to the correct directory, and on the templates the images appear as expected when requested. The problem is within /admin/images/ where the requested version of the image is unavailable, and so the browser shows a broken image icon.
The admin page is looking for a specific size of the image ({your-image-name}.max-165x165.{.jpg|.png|.gif}.
Watching how images move from original_images to images makes it appear that they are only processed after the template they are on is first requested. One idea then might be to create a template listing all the images (with the correct styling) to process them after the data has been loaded in. However doing something like
{% image page.image max-165x165 as test_photo %}
<img src="{{ test_photo.url }}" width="{{ test_photo.width }}" height="{{ test_photo.height }}" alt="{{ test_photo.alt }}" />
Still returns a broken image, and doesn't process the image from the original_images folder to the images folder as I'd have expected. I tried this after the initial data load, and am presuming it's because the image size needs to have a reference within both the database and template?
Is there a way to programmatically force Wagtail to reprocess all the images to generate the size and file name that the image admin page is looking for?
(To mention quickly, if it's relevant, that the images currently sit within the project repo, but will ultimately be a zip file stored on a cloud store and only be imported to the project once requested. Currently, regardless of whether the user wants them or not, the images are included with the Cookiecutter)
Whenever a template (either front-end or within the admin) requires an image at a particular size, it will look in the wagtailimages.Rendition model (or the project-specific Rendition model, if custom image models are in use) to see if one has previously been generated. If so, it will use the existing file; if not, it will generate a new one and add a Rendition record.
If you're getting a broken image, it most likely means that a Rendition record exists (because it's been included in your initial data fixture) but the corresponding image file isn't present in MEDIA_ROOT/images. The proper fix would be to remove the rendition records from your fixture. To fix this after the fact and force all image renditions to be recreated, you can simply delete the contents of the wagtailimages_rendition table.

django-admin and static files

I'm new to django and recently I'm following this tutorial
to write a todo-list app.
In part 2 I should customize the admin's change_list template and add an image into it.
At first I use
<img class='btn' src='static/img/on.png'>
but it turns out to be invalid.
Can anybody figure out what's the problem is? Thanks a lot.
Here is my folder structure
todo-list
todo-app
img
----on.png
----off.png
templates
admin
----change_list.html
todo-list
you can't access the static file( images, css, js ) directly in django
to serve the static files you need to use {{ MEDIA_URL }} or {{STATIC_URL}} for that How do I include image files in Django templates?, and this link
this will helps u :)

What is the right and efficient way of displaying images based on name in Django

I'm really new to Django. I'm having difficulty displaying images based on their name and according to the url pattern.
So basically the url consists of several variables within them and I want to be able to use that to fetch a particular image that is named with those variables.
Example:
localhost:8080/farm/chicken
this would fetch an image inside of my ../static/images/ folder and get:
farm_chicken.jpg
Another example:
localhost:8080/zoo/alligator
would get:
zoo_alligator.jpg
I can fetch the url parameters. So, should I make these image names within my views.py file and pass the names (zoo_alligator) into a context to be retrieved by the template later on? Would this be the correct way?
Thank you for your advice everybody! I appreciate all the help!
You won't actually do something like that, in general. What you should do is to send the image as a context variable from your view function to your template.
If you are using your url node to determine which picture to show, then in your corresponding view function, you are actually using "alligator" or "chicken" to load up the corresponding Animal class.
Once the correct animal object is instantiated, you could send this animal object to your django template and load in the image using a snippet similar to this:-
Like this:-
{% if animal.get_latest_medium_url %}
<img id="animal_image" class="img-rounded left" src="/media/{{ animal_image }}" />
{% endif %}
The get_latest_medium_url is a method in my Merchant class and it computes the url there.
So, should I make these image names within my views.py file and pass
the names (zoo_alligator) into a context to be retrieved by the
template later on? Would this be the correct way?
Sure, this is one way to do it. Something like this:
(r'show/(?P<in_path>.*)$','someapp.image_view')
Then in image_view:
def image_view(request,in_path):
img = in_path.replace('/','_')+'.jpg'
return render(request,'some_template.html',{'path':img})
However, as your view is very simple - you can pass the path directly to the template from urls.py, using direct_to_template:
from django.views.generic.simple import direct_to_template
(r'show/(?P<in_path>.*)$',direct_to_template,{'template':'some_template.html'})
In some_template.html:
<img src="{{ params.in_path }}">
The problem is that you won't get your string formatting done as the default filters do not have a "replace" function. You can easily write a custom filter:
#register.filter
#stringfilter
def format_path(the_path):
return the_path.replace('/','_')+'.jpg'
Then modify the template:
<img src="{{ params.in_path|format_path }}">
You should read the documentation on writing custom filters and tags for more details including where to store the filter code to make sure django can find it.