Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 54730d5

Browse files
committed
Refinement of Assets and conversion of Image.
Writing the migrations when converting over an old plugin to use asset is unfortunately a manual task. But it's not as difficult as it sounds.
1 parent 039ae87 commit 54730d5

File tree

11 files changed

+157
-99
lines changed

11 files changed

+157
-99
lines changed

icekit/admin.py

+15
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
from django.contrib import admin
1010
from django.contrib.contenttypes.models import ContentType
1111
from django.http import JsonResponse
12+
from django.utils.module_loading import import_string
1213
from django.utils.translation import ugettext_lazy as _
14+
from polymorphic.admin import PolymorphicChildModelFilter
1315
from polymorphic.admin import PolymorphicParentModelAdmin
1416

1517
from icekit import models
@@ -166,5 +168,18 @@ class MediaCategoryAdmin(admin.ModelAdmin):
166168
pass
167169

168170

171+
class AssetParentAdmin(PolymorphicParentModelAdmin):
172+
base_model = models.Asset
173+
list_display = ['title', 'get_admin_thumbnail', 'get_child_type', 'caption', ]
174+
list_display_links = ['title']
175+
filter_horizontal = ['categories', ]
176+
list_filter = [PolymorphicChildModelFilter, 'categories']
177+
search_fields = ['title', 'caption', 'admin_notes']
178+
polymorphic_list = True
179+
180+
def get_child_models(self):
181+
return [import_string(kls) for kls in settings.ASSET_CLASSES]
182+
183+
admin.site.register(models.Asset, AssetParentAdmin)
169184
admin.site.register(models.Layout, LayoutAdmin)
170185
admin.site.register(models.MediaCategory, MediaCategoryAdmin)

icekit/assets/__init__.py

-1
This file was deleted.

icekit/assets/apps.py

-8
This file was deleted.

icekit/assets/migrations/__init__.py

Whitespace-only changes.

icekit/assets/models.py

-53
This file was deleted.

icekit/assets/migrations/0001_initial.py renamed to icekit/migrations/0007_asset.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class Migration(migrations.Migration):
1919
('title', models.CharField(help_text='The title is shown in the "title" attribute', max_length=255, blank=True)),
2020
('caption', models.TextField(blank=True)),
2121
('admin_notes', models.TextField(help_text='Internal notes for administrators only.', blank=True)),
22-
('categories', models.ManyToManyField(related_name='assets_asset_related', to='icekit.MediaCategory', blank=True)),
23-
('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_assets.asset_set+', editable=False, to='contenttypes.ContentType', null=True)),
22+
('categories', models.ManyToManyField(related_name='icekit_asset_related', to='icekit.MediaCategory', blank=True)),
23+
('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_icekit.asset_set+', editable=False, to='contenttypes.ContentType', null=True)),
2424
],
2525
options={
2626
'abstract': False,

icekit/models.py

+43
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import six
2+
from django.db import models
3+
from django.utils.translation import ugettext_lazy as _
4+
from fluent_contents.models import ContentItem
5+
from polymorphic.models import PolymorphicModel
6+
17
from . import abstract_models, managers
28

39

@@ -15,3 +21,40 @@ class MediaCategory(abstract_models.AbstractMediaCategory):
1521
A categorisation model for Media assets.
1622
"""
1723
pass
24+
25+
26+
class Asset(PolymorphicModel):
27+
"""
28+
A static asset available for use on a CMS page.
29+
"""
30+
title = models.CharField(
31+
max_length=255,
32+
blank=True,
33+
help_text=_('The title is shown in the "title" attribute'),
34+
)
35+
caption = models.TextField(
36+
blank=True,
37+
)
38+
categories = models.ManyToManyField(
39+
'icekit.MediaCategory',
40+
blank=True,
41+
related_name='%(app_label)s_%(class)s_related',
42+
)
43+
admin_notes = models.TextField(
44+
blank=True,
45+
help_text=_('Internal notes for administrators only.'),
46+
)
47+
48+
def get_admin_thumbnail(self, width=150, height=150):
49+
raise NotImplementedError
50+
get_admin_thumbnail.short_description = "thumbnail"
51+
52+
def get_child_type(self):
53+
return self.polymorphic_ctype
54+
get_child_type.short_description = 'type'
55+
56+
def get_uses(self):
57+
return [item.parent.get_absolute_url() for item in self.assetitem_set().all()]
58+
59+
def __str__(self):
60+
return self.title

icekit/plugins/image/abstract_models.py

+20-22
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,53 @@
11
from django.core.exceptions import ValidationError
22
from django.template import Context
33
from django.template.loader import render_to_string
4+
from django.utils import six
5+
from django.utils.html import format_html
46
from django.utils.safestring import mark_safe
57
from django.db import models
68
from django.utils import six
79
from django.utils.encoding import python_2_unicode_compatible
810
from django.utils.translation import ugettext_lazy as _
911
from fluent_contents.models import ContentItem
12+
from icekit.models import Asset
1013

1114

1215
@python_2_unicode_compatible
13-
class AbstractImage(models.Model):
16+
class AbstractImage(Asset):
1417
"""
1518
A reusable image.
1619
"""
1720
image = models.ImageField(
1821
upload_to='uploads/images/',
1922
verbose_name=_('Image field'),
2023
)
21-
title = models.CharField(
22-
max_length=255,
23-
blank=True,
24-
help_text=_('Can be included in captions'),
25-
)
2624
alt_text = models.CharField(
2725
max_length=255,
2826
help_text=_("A description of the image for users who don't see images. Leave blank if the image has no informational value."),
2927
blank=True,
3028
)
31-
caption = models.TextField(
32-
blank=True,
33-
)
34-
categories = models.ManyToManyField(
35-
'icekit.MediaCategory',
36-
blank=True,
37-
related_name='%(app_label)s_%(class)s_related',
38-
)
39-
admin_notes = models.TextField(
40-
blank=True,
41-
help_text=_('Internal notes for administrators only.'),
42-
)
4329
is_active = models.BooleanField(
4430
default=True,
4531
)
4632

33+
class Meta:
34+
abstract = True
35+
4736
def clean(self):
4837
if not (self.title or self.alt_text):
4938
raise ValidationError("You must specify either title or alt text")
5039

51-
class Meta:
52-
abstract = True
40+
def get_admin_thumbnail(self, width=150, height=150):
41+
try:
42+
from easy_thumbnails.files import get_thumbnailer
43+
except ImportError:
44+
return 'Thumbnail error: easy_thumbnails not installed'
45+
try:
46+
thumbnailer = get_thumbnailer(self.image)
47+
thumbnail = thumbnailer.get_thumbnail({'size': (width, height)})
48+
return format_html('<img class="thumbnail" src="{0}" />'.format(thumbnail.url))
49+
except Exception as ex:
50+
return 'Thumbnail exception: {0}'.format(ex)
5351

5452
def __str__(self):
5553
return self.title or self.alt_text
@@ -79,7 +77,7 @@ class Meta:
7977
verbose_name_plural = _('Images')
8078

8179
def __str__(self):
82-
return six.text_type(self.image)
80+
return six.text_type(self.asset)
8381

8482
@property
8583
def caption(self):
@@ -95,7 +93,7 @@ def caption(self):
9593
@caption.setter
9694
def caption(self, value):
9795
"""
98-
If the caption property is assigned, make it use the
96+
If the caption property is assigned to make it use the
9997
`caption_override` field.
10098
10199
:param value: The caption value to be saved.

icekit/plugins/image/admin.py

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
from django.contrib import admin
22

33
from icekit.utils.admin.mixins import ThumbnailAdminMixin
4+
from polymorphic.admin import PolymorphicChildModelAdmin
45

56
from . import models
67

78

8-
class ImageAdmin(ThumbnailAdminMixin, admin.ModelAdmin):
9-
list_display = ['thumbnail', 'title', 'alt_text',]
10-
list_display_links = ['alt_text', 'thumbnail']
11-
filter_horizontal = ['categories', ]
12-
list_filter = ['categories',]
13-
search_fields = ['title', 'alt_text', 'caption', 'admin_notes', 'image']
14-
9+
class ImageAdmin(PolymorphicChildModelAdmin):
10+
base_model = models.Image
1511
change_form_template = 'image/admin/change_form.html'
1612

17-
# ThumbnailAdminMixin attributes
18-
thumbnail_field = 'image'
19-
thumbnail_options = {
20-
'size': (150, 150),
21-
}
22-
2313
admin.site.register(models.Image, ImageAdmin)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
6+
7+
def create_assets(apps, schema_editor):
8+
# We need to create a new asset for each image
9+
Image = apps.get_model('icekit_plugins_image', 'Image')
10+
Asset = apps.get_model('icekit', 'Asset')
11+
for image in Image.objects.all():
12+
# Create a new asset
13+
asset = Asset()
14+
asset.admin_notes = image.admin_notes
15+
asset.caption = image.caption
16+
asset.title = image.title
17+
asset.save()
18+
asset.categories.add(*image.categories.all())
19+
20+
# Set the asset_ptr on the image
21+
image.asset_ptr = asset
22+
image.save()
23+
24+
25+
class Migration(migrations.Migration):
26+
27+
dependencies = [
28+
('icekit', '0007_asset'),
29+
('icekit_plugins_image', '0008_auto_20160920_2114'),
30+
('icekit', '0006_auto_20150911_0744'),
31+
]
32+
33+
operations = [
34+
# Add the ForeignKey first as not the primary key so we can fake it
35+
migrations.AddField(
36+
model_name='image',
37+
name='asset_ptr',
38+
field=models.OneToOneField(parent_link=True, auto_created=True, default=1, serialize=False, to='icekit.Asset'),
39+
preserve_default=False,
40+
),
41+
# Create asset links for existing images
42+
migrations.RunPython(
43+
create_assets
44+
),
45+
migrations.RemoveField(
46+
model_name='image',
47+
name='admin_notes',
48+
),
49+
migrations.RemoveField(
50+
model_name='image',
51+
name='caption',
52+
),
53+
migrations.RemoveField(
54+
model_name='image',
55+
name='categories',
56+
),
57+
migrations.RemoveField(
58+
model_name='image',
59+
name='id',
60+
),
61+
migrations.RemoveField(
62+
model_name='image',
63+
name='title',
64+
),
65+
# Make asset_ptr the primary key
66+
migrations.AlterField(
67+
model_name='image',
68+
name='asset_ptr',
69+
field=models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='icekit.Asset'),
70+
preserve_default=False,
71+
),
72+
]

icekit/project/settings/_base.py

+2
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@
610610

611611
MIDDLEWARE_CLASSES += ('icekit.publishing.middleware.PublishingMiddleware', )
612612

613+
ASSET_CLASSES = ('icekit.plugins.image.models.Image',)
614+
613615
# MASTER PASSWORD #############################################################
614616

615617
AUTHENTICATION_BACKENDS += ('master_password.auth.ModelBackend', )

0 commit comments

Comments
 (0)