class AssetForm(forms.ModelForm): """ Asset form with restricted asset_type choices.""" asset_type = forms.ModelChoiceField( queryset=models.get_asset_type_model().objects.distinct('id'), label=_("Asset Type") ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) related = self.instance.related qs = models.get_asset_type_model().objects.get_for_model(related) self.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)
from bitfield import BitField from bitfield.forms import BitFieldCheckboxSelectMultiple from django.contrib import admin from django.contrib.contenttypes.admin import GenericTabularInline from image_assets import models, forms @admin.register(models.get_asset_type_model()) class AssetTypeAdmin(admin.ModelAdmin): formfield_overrides = { BitField: {'widget': BitFieldCheckboxSelectMultiple}, } class AssetsInline(GenericTabularInline): model = models.get_asset_model() formset = forms.AssetFormSet
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 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 __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) related = self.instance.related qs = models.get_asset_type_model().objects.get_for_model(related) self.fields["asset_type"].queryset = qs
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)