Reputation: 827
I have a "Category" model. I want to have it so every time I create a category it creates a directory in my media
folder. From there I want to be able to upload images to the relevant folders and have a gallery in my category view that loops through every image in said categories directory.
category.html
<div class="container">
<div class="row">
{% for image in images %}
<div class="col-md-4">
<a href="/media/{{ image }}"> <img src="/media/{{ image }}" class="img-responsive img-thumbnail" width="304" height="236"/>
</a>
</div>
{% endfor %}
</div>
</div>
views.py
def category_detail_view(request, slug):
try:
category = Category.objects.get(slug=slug)
images = os.listdir(settings.MEDIA_ROOT)
context = {
"images": images,
}
except Category.DoesNotExist:
return HttpResponseNotFound()
return render(request, 'main/category_detail.html', context)
models.py
class Category(models.Model):
category_title = models.CharField(max_length=200)
category_image = models.ImageField(upload_to="category")
category_description = models.TextField()
slug = models.SlugField(max_length=200, unique=True, default=1)
class Meta:
verbose_name_plural = "Categories"
unique_together = ("category_title", "slug")
def __str__(self):
return self.category_title
This code seems to work but only for the MEDIA_ROOT
. I want to loop through the current category
Upvotes: 0
Views: 126
Reputation: 1149
Ok, let's do it in your view
def category_detail_view(request, slug):
category = get_object_or_404(Category, slug=slug)
# Get the absolute path where the category images should be
category_imgs_path = os.path.abspath(os.path.join(
settings.MEDIA_ROOT,
category.slug))
# Check if the path exists, if not, create it
if not os.path.isdir(category_imgs_path):
os.mkdir(category_imgs_path)
images = os.listdir(category_imgs_path)
context = {
"images": images,
}
return render(request, 'main/category_detail.html', context)
Maybe it should be better to create the category images path when de Category itself it's created instead of viewed, You've not published the code where you create de Category instance, so, I've did it in your view, it should work anyway.
Note that I've added the usage of get_object_or_404 django shortcut to avoid the try/except, docs here -> https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/#get-object-or-404
You should consider filtering the contents listed in images
to ensure only images are in that variable using os.walk
, glob
or something similar.
Hopes this accomplish your needs, if not, don't hesitate to ask for it.
If you are creating your instance from the Admin interface
Since you are creating your instance from the admin interface, you can create the path overriding the save_model
method in your ModelAdmin as follows:
class CategoryAdmin(ModelAdmin):
(...)
def save_model(self, request, obj, form, change):
category_imgs_path = os.path.abspath(os.path.join(
settings.MEDIA_ROOT,
obj.slug))
# Check if the path exists, if not, create it
if not os.path.isdir(category_imgs_path):
os.mkdir(category_imgs_path)
super().save_model(request, obj, form, change)
Upvotes: 1