GTA.sprx
GTA.sprx

Reputation: 827

Gallery in Django

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

Answers (1)

Gabriel
Gabriel

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

Related Questions