Save images with generic foreign key

Django April 15, 2018 python

Django model to save images with generic foreign key

python
import os
import datetime
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType


def get_upload_path(instance, filename):
    name = instance.__class__.__name__.lower()
    return os.path.join('{}_{}_{}/{}/{}'.format(
        datetime.datetime.now().day,
        datetime.datetime.now().month,
        datetime.datetime.now().year, name, filename))


class ContentManager(models.Manager):
    def all(self):
        qs = super().all()
        return qs

    def filter_by_instance(self, instance):
        content_type = ContentType.objects.get_for_model(instance.__class__)
        obj_id = instance.id
        qs = super().filter(
            content_type=content_type, object_id=obj_id)
        return qs


class Media(models.Model):
    image = models.ImageField(upload_to=get_upload_path)
    caption = models.CharField(blank=True, max_length=255)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)
    is_published = models.BooleanField(default=False)
    order = models.PositiveSmallIntegerField(
            default=0, blank=False, null=False)

    objects = ContentManager()

    class Meta:
        default_related_name = 'media'
        verbose_name = 'media'
        verbose_name_plural = 'media'
        ordering = ['order']

    def get_object(self):
        ct = ContentType.objects.get_for_model(self.content_object)
        obj = ct.get_object_for_this_type(pk=self.object_id)
        return obj

    def filename(self):
        return os.path.basename(self.image.name)

    def __str__(self):
        return self.filename()