Iterate through a static image folder in django - python

I am trying to get all image link present in a folder. Currently, I am assigning the link manually. But, I want my django to get all images from a specific folder irrespective of their names.
<li>
<img src="{% static "styles/jamia/1.jpg" %}">
</li>
<li>
<img src="{% static "styles/jamia/2.jpg" %}">
</li>
I am looking for something like:
{% for file in {% static "styles/jamia/" %} %}
<img src="{{file}}" alt="">
{% endfor %}
All images are present in jamia folder.

This isn't something Django has built in. But Django is just Python, and you can use normal Python file functions to get your list in the view:
files = os.listdir(os.path.join(settings.STATIC_ROOT, "styles/jamia"))

This seems to have been answered in parts before, but probably requires some searching for all the answers. So in an attempt to provide a complete answer to this questions in one place:
In views.py you would want to do something like the other answer says:
context_dict = {}
files = os.listdir(os.path.join(settings.STATIC_DIR, "styles/jamia/"))
context_dict['files'] = files
return render(request, 'home.html', context=context_dict)
Then in your html template you can loop over your images. In addition, we make use of with to join the root to the static file with those names pulled out in the views.py, but you could have concatenated the whole path in views and not needed with. So, in home.html:
{% for file in files %}
{% with 'images/'|file as image_static %}
<img src="{% static image_static %}" alt="">
{% endwith %}
{% endfor %}

Related

Django database stored images showing only text descriptions

I am trying to store images on a database and then display them on a Django template. For some reason Django is only showing the alt (alternate - html attribute) instead of the actual image.
This is the template
{% extends "myapp/layout.html" %}
{% load static %}
{% block body %}
<div class="sidenav">
Gallery
About
Contact
</div>
<div class="main">
<h2>Gallery</h2>
{% for image in images %}
<img class="gallery" src="{% static '{{image.image.url}}' %}" alt="{{image.description}}">
{% endfor %}
</div>
{% endblock %}
This is my model
from django.db import models
# Create your models here.
class Image(models.Model):
image = models.ImageField(upload_to='images/')
description = models.CharField(max_length=50)
def __str__(self):
return "Description of image: " + self.description
This is what I'm seeing
These are normally media urls, so you render these with:
<img class="gallery" src="{{ image.image.url }}" alt="{{image.description}}">
You need to add the views regarding media files to the urlpatterns, as described in the documentation.
or if these really only contain a path relative to the static folder, you work with:
<img class="gallery" src="{% static image.image.url %}" alt="{{image.description}}">
But it is not very likely that this is the case.
Regardless what the Note that Django only serves static/media files in debug mode (DEBUG = True). If you run this on production, you will need to configure apache/nginx/… to serve static/media files.

Django: Using a for loop to view all images from my db - using img src

I am currently learning Django and making my first steps. I try to build a webgallery to learn all the basic stuff. I successfully displayed some images using static files. So I tried saving Images through ImageFields and "upload_to" in my DB, saving it to my static directory. I tried to display everyone of them with a for loop in an tag. My img displays properly with using a {% static %} tag but when I try to insert a {{ }} Tag it isn't working, although it's the same url it doesn't work.
I tried changing my STATIC FILE in settings.py
I tried various other forms of nesting my {{}} in there
Reading the docs to staticfile https://docs.djangoproject.com/en/2.2/howto/static-files/
This thread Display an image located in the database in Django
This thread https://docs.djangoproject.com/en/2.2/topics/files/#using-files-in-models
My Code:
<p>Overview</p>
{% block content %}
<div>
{% for image in images %}
{{ image.img_photo }} <!-- webgalleries/test.jpg -->
{% load static %}
<img src="{% static 'webgalleries/test.jpg' %}" alt="{{ image }}"> <!-- working -->
<img src="{% static '{{ image.img_photo }}' %}" alt="{{ image }}"> <!-- not working -->
{% empty %}
<p>No content</p>
{% endfor %}
</div>
{% endblock content %}
I expect the output to be an img from my static directory.
A hint, some advice or other forms of help is highly appreciated.
Thank you so much!
okay if you want to display images from database you should do these steps :
1- go to your settings.py and write this code there ,
MEDIA_ROOT= os.path.join(BASE_DIR,"media")
MEDIA_URL= "/media/"
2- then create new folder in your project called 'media' and create folder inside 'media' called 'images' (finally result will be like this 'media/images' )
3- go to your model.py in your class that having 'img_photo'
and you should write the model like this
class Images(models.Model):
img_photo = models.ImageField(upload_to='images/',null=True, blank=True)
def get_image(self):
if self.img_photo and hasattr(self.img_photo, 'url'):
return self.img_photo.url
else:
return '/path/to/default/image'
def __str__(self):
return self.img_photo
4- go to admin.py then write :
from yourapp.models import Images
then add this line below
admin.site.register(Images)
then open your terminal or console and write :
1- python manage.py makemigrations
2- python manage.py migrate
5- in html code you must write :
{% for image in Images %}
<img src="{{ image.get_image }}" >
{% endfor %}
go to admin panel and upload any photo for test

How to render data to a {% included a.html %} template in Django

I have a rank.html which is a publicly sharing template for many other templates through {% include rank.html %} method.
This template will display the 48 hours hot news base on the click number.
Here is the view.py:
def rank(self, request):
hot_news_48h = h_mostViewed(48, News, '-pv')
return render(request, "rank.html", {
'hot_news_48h': hot_news_48h,})
h_mostViewed(48, News, '-pv') is a function,that can fetch most viewed(clicked) post within 48 hours.It works.
Here is the rank.html:
<ul>
{% for hot_view in hot_news_48h %}
<li>
<a href="{% url 'news:news_detail' hot_view.pk %}" >
<img src="{{ MEDIA_URL }}{{ hot_view.image }}" >
</a>
<a href="{% url 'news:news_detail' hot_view.pk %}">
<h6>{{ hot_view.title }}</h6>
</a>
</div>
</li>
{% endfor %}
</ul>
Here is the url.py:
path('hot_news', views.rank, name="hot_news")
The problem is,I can only get the html ,but can't receive the data.
But if I give up {% include rank.html %} method and insert the rank.html's code directly inside each template which need this function, I can get the data.
Take new_detail.html template as an example:
Here is the view.py:
def newsDetailView(request, news_pk):
news = get_object_or_404(News, id=news_pk)
all_comments = NewsComments.objects.filter(news=news)
news.comment_nums = all_comments.count()
news.save()
News.objects.filter(id=news_pk).update(pv=F('pv') + 1)
hot_news_48h = h_mostViewed(48, News, '-pv')
relative_news = News.objects.filter(tag__id__in=news.tag.all()).exclude(id=news_pk)[:6]
return render(request, "news_detail.html", {
'news': news,
'all_comments': all_comments,
'hot_news_48h': hot_news_48h,
'relative_news': relative_news
})
Here is the urls.py:
path('-<int:news_pk>', views.newsDetailView, name="news_detail"),
So above,I directly inserted rank.html's code into new_detail.html and it works I can get the data.
My question is what should I do or correct,so that I can get the data in {% include rank.html %} method. Because {% include rank.html %} is simple and flexible.I don't want to repeat the same code in several same template.
Thank you so much for your patience!
How about this:
- Create a folder "templatetags" in your application and add a file "news_tags.py" or name it what you want. Then you can define the tags you need:
from django.template import Library
from your_app.models import your_model
register = Library()
#register.inclusion_tag('your_app/your_template.html')
def hot_news(num, order):
objects = News.objects.order_by(order)[:num]
result['objects'] = objects
return result
In your templates you then do the following:
{% load news_tags %}
{% hot_news 48 '-pv' %}
Then create a template as your already did and reference it in the inclusion tag. Then it should work properly.
If you want it to work for multiple models you can have a look at this: https://docs.djangoproject.com/el/2.1/ref/applications/
The apps framework allows you to fetch models from a string input.
I finally solved the issue by Creating custom context processor.https://www.youtube.com/watch?v=QTgkGBjjVYM

How can i make a custom list of files in django?

I have an app in Django where users upload some files(xlsx), the information gets extracted and the files are stored in /media.
I want a page/view where the users should be able to browse through the files by folder structure or alphabetically and they should be able to download them from the server.
What i have now is as basic as it gets:
this is the .html
{% block Content%}
{% if documents %}
<ul id="files_ul">
{% for document in documents %}
<li>
{{ document.docfile.name }}
</li>
{% endfor %}
</ul>
{% else %}
<p> No documents. </p>
{% endif %}
{% endblock %}
I have a model named Document and i've added this:
+ static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
to urls.py which i know it's not secure.
I don't need something like Filer because i already have that but i didn't yet figure out how to configure.
I only know python and that not extensively and i'm new to Django so any help would be really appreciated.
It would be of great help if you could show me at least how to change the name of the files that appear now in this view,
document.docfile.name
Results in folder1/folder2/filename and i would want only the filename to appear.
Model
class Document(models.Model):
def filename(self):
return os.path.basename(self.file.name)
upload_user=models.ForeignKey(User, related_name='documents')
upload_time=models.DateTimeField(auto_now_add=True)
docfile=models.FileField(upload_to='documents/%Y/%m')
in your model where you have defined filefield put this function
def filename(self):
return os.path.basename(self.docfile.name)
and in template
{{ document.filename }}

django endless pagination(twitter style) not working - .endless_more class not in html but used in js

i am using django endless pagination . its working normally that just shows the numbers at the bottom .
but, i tried to integrate twitter style into it:
http://django-endless-pagination.readthedocs.org/en/latest/twitter_pagination.html#pagination-on-scroll
I have followed exactly but didnt work .
When I looked at the js code, i have seen they have used .endless_more in js class, but the generated html file has only two classes for links :
1)endless_page_current
2)endless_page_link
but they used a.endless_more in js.
Can you tell me the correct way to implement?
Thanks
Views :
from endless_pagination.decorators import page_template
#page_template("my_index_page.html")
def myview(request,template='my_index.html', extra_context=None):
data = {}
if extra_context is not None:
data.update(extra_context)
myobj = Myobj.objects.all()
data['myobj'] = myobj
return render_to_response(template, data, context_instance=RequestContext(request))
Template :
my_index.html
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ STATIC_URL }}js/endless.js"></script>
<script src="{{ STATIC_URL }}js/endless_on_scroll.js"></script>
{% include page_template %}
my_index_page.html
{% load templatetags %}
<center>
<div>
{% load endless %}
{% paginate myobj %}
{% for obj in myobj %}
{{ obj.name }}
{% endfor %}
{% show_pages %}
</div>
<center>
Here, I seriously beleive that i need to add some classes like endless_more , which the django-endless-documentation missed.
i'm using that on my portal, and it seems fine your code, you just missed one thing
{% show_more %}
that's what actually enables the twitter-style infinite pagination
edit here:
you may want to add this too:
<script type="text/javascript" charset="utf-8">
var endless_on_scroll_margin = 20;
</script>
where "20" is the number of pixels (from the bottom of the page) that triggers the scrolling
you may want to try more than one value till you get the perfect one for your project
see here and here

Categories