예제 #1
0
class AssetFormSet(BaseGenericInlineFormSet):
    model = models.get_asset_model()

    def __init__(self, data=None, files=None, instance=None, save_as_new=False,
                 prefix=None, queryset=None, **kwargs):
        if not kwargs.get('initial') and not (data or files):
            kwargs['initial'] = self.construct_initial(instance)
        super().__init__(data, files, instance, save_as_new, prefix, queryset,
                         **kwargs)

    @staticmethod
    def construct_initial(instance):
        asset_type_model = models.get_asset_type_model()
        initial = []
        for asset_type in asset_type_model.objects.get_required(instance):
            initial.append({'asset_type': asset_type.pk})
        return initial

    def add_fields(self, form, index):
        super().add_fields(form, index)
        qs = models.get_asset_type_model().objects.get_for_model(self.instance)
        form.fields['asset_type'].queryset = qs

    def clean(self):
        super().clean()
        if not self.is_valid():
            return
        duplicated_asset_types = set()
        added_asset_types = set()
        qs = models.get_asset_type_model().objects.get_required(self.instance)
        required_asset_types = set(qs.values_list('pk', flat=True))
        for asset_data in self.cleaned_data:
            active = asset_data.get('active')
            if not active:
                # We only perform extra validation for active assets
                continue
            asset_type = asset_data.get('asset_type')
            if not asset_type:
                # empty field value
                continue
            if asset_type.pk in added_asset_types:
                # there are more than one active assets of this type
                duplicated_asset_types.add(asset_type.pk)
            # track whether there are active assets for all required types
            added_asset_types.add(asset_type.pk)

        errors = []
        missing = required_asset_types - added_asset_types
        if missing:
            qs = models.get_asset_type_model().objects.filter(
                pk__in=missing).values_list('slug', flat=True)
            msg = _("Missing required asset types: %s")
            errors.append(ValidationError(msg % ', '.join(qs)))
        if duplicated_asset_types:
            qs = models.get_asset_type_model().objects.filter(
                pk__in=duplicated_asset_types).values_list('slug', flat=True)
            msg = _("Duplicate active assets for types: %s")
            errors.append(ValidationError(msg % ', '.join(qs)))
        if errors:
            raise ValidationError(errors)
예제 #2
0
class AssetsInline(GenericTabularInline):
    model = models.get_asset_model()
    formset = forms.AssetFormSet
예제 #3
0
from typing import Type

from django.db.models.signals import pre_delete
from django.dispatch import receiver

from image_assets import models


# noinspection PyUnusedLocal
@receiver(pre_delete, sender=models.get_asset_model())
def move_asset_file_to_deleted_asset(
        sender, *, instance: models.Asset, **kwargs):
    """ When asset is deleted, it's file is moved to deleted asset instance."""
    models.get_deleted_asset_model().objects.create(
        image=instance.image,
        content_type_id=instance.content_type_id,
        object_id=instance.object_id,
        asset_type_id=instance.asset_type_id)


# noinspection PyUnusedLocal
@receiver(pre_delete, sender=models.get_deleted_asset_model())
def delete_asset_file_for_deleted_asset(
        sender, *, instance: models.DeletedAsset, **kwargs):
    """
    When deleted asset is deleted from db, it's file is purged from storage.
    """
    instance.image.delete(save=False)
예제 #4
0
import io
from typing import Tuple, Optional, Iterable

from PIL import Image
from django.contrib.contenttypes.models import ContentType
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models.base import ModelBase, Model

from image_assets import models

AssetType = models.get_asset_type_model()
Asset = models.get_asset_model()

try:
    from image_assets.tests.factories import *
except ImportError:  # pragma: no cover
    # factory-boy not installed, no default fuzzy attributes will be available
    AssetTypeFactory = AssetType.objects
    AssetFactory = Asset.objects

__all__ = ["ImageAssetsMixin"]


class ImageAssetsMixin:
    @classmethod
    def create_image(cls,
                     dimensions: Tuple[int, int] = (60, 30),
                     color: str = "red") -> Image.Image:
        """ Creates valid image."""
        return Image.new('RGB', dimensions, color=color)
예제 #5
0
 def test_str(self):
     """ Check __str__ method."""
     self.assertIsInstance(self.asset.__str__(), str)
     empty = assets_models.get_asset_model()()
     self.assertIsInstance(empty.__str__(), str)