def test_register_function(self): class RegisterFunction(models.Model): pass register_snippet(RegisterFunction) self.assertIn(RegisterFunction, SNIPPET_MODELS)
@python_2_unicode_compatible class Organization(models.Model): name = models.CharField(max_length=100) website = models.URLField(max_length=255) logo = models.ForeignKey('images.AttributedImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') def __str__(self): return self.name register_snippet(Organization) Organization.panels = [ FieldPanel('name'), FieldPanel('website'), ImageChooserPanel('logo'), ] class EventListPage(PaginatedListPageMixin, Page): subpage_types = ['EventPage'] events_per_page = models.IntegerField(default=20) counter_field_name = 'events_per_page' counter_context_name = 'events'
google = models.URLField(blank=True, null=True) panels = [ ImageChooserPanel('logo'), FieldPanel('title'), FieldPanel('subtitle'), FieldPanel('facebook'), FieldPanel('twitter'), FieldPanel('linkedin'), FieldPanel('google'), ] def __unicode__(self): return self.title register_snippet(Branding) # about page class Teaser(models.Model): page = ParentalKey('pages.AboutPage', related_name='teasers') image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', ) title = models.CharField(max_length=100) subtitle = models.CharField(max_length=100) link = models.ForeignKey(
('AC', 'Adaptive Courseware'), ('CT', 'Customized Tools'), ) ally_category = models.CharField(max_length=2, choices=ALLY_CATEGORY) logo = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) heading = models.CharField(max_length=255) description = RichTextField() link_url = models.URLField(blank=True, help_text="Call to Action Link") link_text = models.CharField(max_length=255, help_text="Call to Action Text") api_fields = ('ally_category', 'logo', 'heading', 'description', ) panels = [ FieldPanel('ally_category'), ImageChooserPanel('logo'), FieldPanel('heading'), FieldPanel('description'), ] def __str__(self): return self.heading register_snippet(Ally)
class Meta: ordering = ['name'] verbose_name_plural = 'Countries' def __unicode__(self): return self.name @property def libraries(self): return Library.objects.filter(city__country=self) @property def publishers(self): return Publisher.objects.filter(city__country=self) register_snippet(Country) class City(TimeStampedModel): name = models.CharField(max_length=64) country = models.ForeignKey(Country, related_name='cities') panels = [ FieldPanel('name', classname='full title'), SnippetChooserPanel('country', Country) ] class Meta: ordering = ['name'] unique_together = ['country', 'name'] verbose_name_plural = 'Cities'
containing_page=instance, featured_item=featured_item, feature_style=style, image_overlay_opacity=opacity, ) @python_2_unicode_compatible class SiteDefaults(models.Model): site = models.OneToOneField('wagtailcore.Site', related_name='default_settings', unique=True) default_external_article_source_logo = models.ForeignKey( 'images.AttributedImage', related_name='+') contact_email = models.EmailField(blank=True, default="") def __str__(self): return "{}".format(self.site) class Meta: verbose_name_plural = "Site Defaults" panels = [ FieldPanel('site'), ImageChooserPanel('default_external_article_source_logo'), FieldPanel('contact_email'), ] register_snippet(SiteDefaults)
panels = [ MultiFieldPanel([ FieldPanel('header'), FieldPanel('content'), ]), ] def __unicode__(self): s = 'Main Footer Text: <b>%s</b>' % (self.header) return mark_safe(s) class SecondaryFooterText(models.Model): header = models.CharField(max_length=100, help_text="Header text to display above text. Ex. 'Welcome'") content = RichTextField(blank=True) panels = [ MultiFieldPanel([ FieldPanel('header'), FieldPanel('content'), ]), ] def __unicode__(self): s = 'Secondary Footer Text: <b>%s</b>' % (self.header) return mark_safe(s) register_snippet(Menu) register_snippet(MainFooterText) register_snippet(SecondaryFooterText)
return sorted(chain(article_list, series_list), key=lambda x: x.first_published_at, reverse=True) class Meta: ordering = ["name", ] search_fields = [ index.SearchField('name', partial_match=True), ] panels = [ FieldPanel("name"), ] register_snippet(Topic) class TopicListPage(RoutablePageMixin, ThemeablePage): articles_per_page = models.IntegerField(default=20) @property def topics(self): popular_topics = Topic.objects.annotate( num_articles=Count('article_links') + Count('articles') + Count('series')).order_by("-num_articles")[:25] return sorted(popular_topics, key=lambda x: x.name) @route(r'^$', name="topic_list") def topics_list(self, request): context = { "self": self,
logo = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') heading = models.CharField(max_length=255) description = RichTextField() link_url = models.URLField(blank=True, help_text="Call to Action Link") link_text = models.CharField(max_length=255, help_text="Call to Action Text") api_fields = ( 'ally_category', 'logo', 'heading', 'description', ) panels = [ FieldPanel('ally_category'), ImageChooserPanel('logo'), FieldPanel('heading'), FieldPanel('description'), ] def __str__(self): return self.heading register_snippet(Ally)
api_fields = ( 'heading', 'description', ) panels = [ FieldPanel('heading'), FieldPanel('description'), ] def __str__(self): return self.heading register_snippet(Resource) class StudentResources(models.Model): resource = models.ForeignKey( Resource, null=True, help_text="Manage resources through snippets.", related_name='+') link_external = models.URLField("External link", blank=True) link_page = models.ForeignKey('wagtailcore.Page', null=True, blank=True, related_name='+') link_document = models.ForeignKey('wagtaildocs.Document', null=True,
HomePage.content_panels = Page.content_panels + [ PageChooserPanel("featured_item", "wagtailcore.Page"), FieldPanel("number_of_rows_of_articles"), FieldPanel("number_of_columns_of_articles"), FieldPanel("number_of_rows_of_external_articles"), FieldPanel("number_of_rows_of_visualizations"), ] @python_2_unicode_compatible class SiteDefaults(models.Model): site = models.OneToOneField('wagtailcore.Site', related_name='default_settings', unique=True) default_external_article_source_logo = models.ForeignKey( 'images.AttributedImage', related_name='+' ) def __str__(self): return "{}".format(self.site) class Meta: verbose_name_plural = "Site Defaults" panels = [ FieldPanel('site'), ImageChooserPanel('default_external_article_source_logo') ] register_snippet(SiteDefaults)
from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel class BaseTemplate(models.Model): title = models.CharField(max_length=255, blank=True) filename = models.CharField(max_length=255, blank=True) panels = [ FieldPanel('title'), FieldPanel('filename'), ] def __unicode__(self): return self.title register_snippet(BaseTemplate) @register_setting class GeneralSiteSettings(BaseSetting): base_template = models.ForeignKey(BaseTemplate, null=True) template_dir = models.CharField(max_length=255, blank=True) google_analytics_property = models.CharField(max_length=255, blank=True) panels = [ SnippetChooserPanel('base_template'), FieldPanel('template_dir'), FieldPanel('google_analytics_property'), ]
] EventIndexPage.promote_panels = Page.promote_panels # EventPage class EventCategory(models.Model): title = models.CharField(max_length=64, unique=True) def __unicode__(self): return self.title class Meta: verbose_name_plural = 'Event categories' register_snippet(EventCategory) class EventPageCategory(Orderable): page = ParentalKey('EventPage', related_name='categories') category = models.ForeignKey(EventCategory) panels = [ SnippetChooserPanel('category') ] class EventPageCarouselItem(Orderable, AbstractCarouselItem): page = ParentalKey('EventPage', related_name='carousel_items')
page = ParentalKey("wagtailcore.Page", related_name="advert_placements") advert = models.ForeignKey("swimtheme.Advert", related_name="+") class Advert(models.Model): page = models.ForeignKey("wagtailcore.Page", related_name="adverts", null=True, blank=True) url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [PageChooserPanel("page"), FieldPanel("url"), FieldPanel("text")] def __unicode__(self): return self.text register_snippet(Advert) # Advert Snippet class CalloutPlacement(models.Model): page = ParentalKey("wagtailcore.Page", related_name="callout_placements") callout = models.ForeignKey("swimtheme.Advert", related_name="+") class Callout(models.Model): page = models.ForeignKey("wagtailcore.Page", related_name="callout", null=True, blank=True) url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255)
@python_2_unicode_compatible class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [ FieldPanel('url'), FieldPanel('text'), ] def __str__(self): return self.text register_snippet(Advert) # AlphaSnippet and ZuluSnippet are for testing ordering of # snippets when registering. They are named as such to ensure # thier ordering is clear. They are registered during testing # to ensure specific [in]correct register ordering # AlphaSnippet is registered during TestSnippetOrdering @python_2_unicode_compatible class AlphaSnippet(models.Model): text = models.CharField(max_length=255) def __str__(self): return self.text
return self.project.__unicode__() + u'\'s ' + self.image.__unicode__() + u' image' panels = [ ImageChooserPanel('image'), ] class PortfolioMetaFieldKey(models.Model): text = models.CharField(max_length=255) class Meta: verbose_name_plural = "MetaField Keys" def __unicode__(self): return self.text register_snippet(PortfolioMetaFieldKey) class ProjectCategoryMetaFieldDefaultKeys(Orderable): category = ParentalKey('portfolio.ProjectCategory',related_name='default_metafields') key = models.ForeignKey(PortfolioMetaFieldKey,related_name="default_to") class Meta: verbose_name_plural = "Portfolio Default MetaKeys" def __unicode__(self): return self.category.__unicode__() + u'\'s default key ' + self.key.__unicode__() panels=[ SnippetChooserPanel('key', PortfolioMetaFieldKey), ]
panels = [ MultiFieldPanel((FieldPanel('first_name'), FieldPanel('middle_name'), FieldPanel('last_name'), FieldPanel('classification', classname='full'), FieldPanel('about', classname='full'), ), "Owner Information"), MultiFieldPanel((FieldPanel('block'), FieldPanel('lot'), FieldPanel('street'), FieldPanel('purok'), FieldPanel('sitio'), FieldPanel('barangay'), FieldPanel('municipality'), FieldPanel('province'), FieldPanel('region'), ), "Address"), ] def __str__(self): full_name = [] if self.first_name: full_name.append(self.first_name) if self.middle_name: full_name.append(self.middle_name[:1] + '.') if self.last_name: full_name.append(self.last_name) return ' '.join(full_name) register_snippet(Owner)
class FormPage(AbstractEmailForm): pass FormPage.content_panels = [ FieldPanel('title', classname="full title"), InlinePanel(FormPage, 'form_fields', label="Form fields"), MultiFieldPanel([ FieldPanel('to_address', classname="full"), FieldPanel('from_address', classname="full"), FieldPanel('subject', classname="full"), ], "Email") ] # Snippets class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [ FieldPanel('url'), FieldPanel('text'), ] def __unicode__(self): return self.text register_snippet(Advert)
from django.db import models from django.utils.encoding import python_2_unicode_compatible from wagtail.wagtailsnippets.models import register_snippet @python_2_unicode_compatible class Interactive(models.Model): name = models.TextField() template = models.TextField() def __str__(self): return self.name register_snippet(Interactive)
@python_2_unicode_compatible class ZuluSnippet(models.Model): text = models.CharField(max_length=255) def __str__(self): return self.text # Register model as snippet using register_snippet as both a function and a decorator class RegisterFunction(models.Model): pass register_snippet(RegisterFunction) @register_snippet class RegisterDecorator(models.Model): pass # A snippet model that inherits from index.Indexed can be searched on @register_snippet class SearchableSnippet(models.Model, index.Indexed): text = models.CharField(max_length=255) search_fields = [
panels = [ ImageChooserPanel('image'), FieldPanel('embed_url'), FieldPanel('caption'), MultiFieldPanel(LinkFields.panels, "Link"), ] def __unicode__(self): return self.caption class Meta: verbose_name = u"头部滚动图" register_snippet(CarouselItem) # Head imgs class HeadImage(models.Model): image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) caption = models.CharField(max_length=255, blank=False) panels = [ ImageChooserPanel('image'), FieldPanel('caption') ]
url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) tags = TaggableManager(through=AdvertTag, blank=True) panels = [ FieldPanel('url'), FieldPanel('text'), FieldPanel('tags'), ] def __str__(self): return self.text register_snippet(Advert) @python_2_unicode_compatible class AdvertWithTabbedInterface(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) something_else = models.CharField(max_length=255) advert_panels = [ FieldPanel('url'), FieldPanel('text'), ] other_panels = [ FieldPanel('something_else'),
FieldPanel('title', classname="full title"), FieldPanel('slug', classname="col6"), ColorFieldPanel('color', classname="col6 colorpicker-field"), ] def get_children(self): return class Meta: verbose_name = _('Category') verbose_name_plural = _('Categories') def __unicode__(self): return u"%s" % self.title register_snippet(Category) class ArticleMixin(models.Model): author = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) date = models.DateField(null=True, blank=True) category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.SET_NULL) excerpt = RichTextField(blank=True, verbose_name=_('Excerpt')) subtitle = models.CharField(max_length=255, null=True, blank=True) styles_override = models.TextField(null=True, blank=True) class Meta: abstract = True BASE_ARTICLE_CONTENT_PANELS = [ FieldPanel('title'), FieldPanel('subtitle'),
panels = [ ImageChooserPanel('logo'), FieldPanel('title'), FieldPanel('subtitle'), FieldPanel('facebook'), FieldPanel('twitter'), FieldPanel('linkedin'), FieldPanel('google'), ] def __unicode__(self): return self.title register_snippet(Branding) # about page class Teaser(models.Model): page = ParentalKey('pages.AboutPage', related_name='teasers') image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', ) title = models.CharField(max_length=100) subtitle = models.CharField(max_length=100)
ImageChooserPanel('feed_image'), ] class Navigation(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(max_length=255) navigation = StreamField([ ('menu_block', blocks.StructBlock([ ('title', blocks.CharBlock()), ('menu_items', blocks.ListBlock(blocks.StreamBlock([ ('link_external', blocks.StructBlock([ ('caption', blocks.CharBlock()), ('url', blocks.CharBlock()), ])), ('link_page', blocks.PageChooserBlock()), ])))])), ], blank=True) panels = [ FieldPanel('title'), FieldPanel('slug'), StreamFieldPanel('navigation'), ] def __unicode__(self): return self.title register_snippet(Navigation)
FieldPanel('title', classname="full title"), StreamFieldPanel('body'), ] class Social(models.Model): number = models.CharField('Телефон', blank=True, max_length=80 ) body = models.CharField("Тело", blank=True, max_length=80 ) panels = [ FieldPanel('body'), FieldPanel('number'), ] def __str__(self): return self.body class Meta: verbose_name = "Телефон" verbose_name_plural = "Телефоны" register_snippet(Social)
null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ PageChooserPanel('page', 'insoft.CustomerPage'), FieldPanel('title'), ImageChooserPanel('emblem') ] def __unicode__(self): return self.title register_snippet(Customer) # Products class ProductsPage(Page): subpage_types = ['insoft.ProductCategoryPage'] content = RichTextField(_('Content'), blank=True, null=True) class Meta: db_table = 'insoft_products_page' verbose_name = _('Products page') ProductsPage.content_panels = [ FieldPanel('title', classname='full title'), FieldPanel('content', classname='full'),
class Organization(models.Model): name = models.CharField(max_length=100) website = models.URLField(max_length=255) logo = models.ForeignKey( 'images.AttributedImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) def __str__(self): return self.name register_snippet(Organization) Organization.panels = [ FieldPanel('name'), FieldPanel('website'), ImageChooserPanel('logo'), ] class EventListPage(Page): subpage_types = ['EventPage'] events_per_page = models.IntegerField(default=20) @property
body = RichTextField() summary = RichTextField(blank=True) slug = models.SlugField() panels = [ PageChooserPanel('page'), FieldPanel('title'), FieldPanel('summary'), FieldPanel('body', classname="full"), FieldPanel('slug'), MultiFieldPanel(LinkFields.panels, "Link"), ] def __unicode__(self): return u"{0}[{1}]".format(self.title, self.slug) register_snippet(ContentBlock) class Testimonial(LinkFields): page = models.ForeignKey( Page, related_name='testimonials', null=True, blank=True ) name = models.CharField(max_length=150) photo = models.ForeignKey( Image, null=True, blank=True, on_delete=models.SET_NULL ) text = models.CharField(max_length=255)
class NavigationMenu(ClusterableModel): menu_name = models.CharField(max_length=255, null=False, blank=False) def __str__(self): return self.menu_name NavigationMenu.panels = [ edit_handlers.FieldPanel('menu_name', classname='full title'), edit_handlers.InlinePanel('menu_items', label="Menu Items") ] register_snippet(NavigationMenu) register_snippet(RSSImport) # Blocks class RSSImportBlock(core_blocks.StructBlock): feed = snippet_blocks.SnippetChooserBlock( required=True, target_model=RSSImport) class Meta: template = 'home/blocks/rss_import_block.html' icon = 'snippet' label = 'RSS Import' class InlineImageBlock(core_blocks.StructBlock):
# thier ordering is clear. They are registered during testing # to ensure specific [in]correct register ordering # AlphaSnippet is registered during TestSnippetOrdering @python_2_unicode_compatible class AlphaSnippet(models.Model): text = models.CharField(max_length=255) def __str__(self): return self.text # ZuluSnippet is registered during TestSnippetOrdering @python_2_unicode_compatible class ZuluSnippet(models.Model): text = models.CharField(max_length=255) def __str__(self): return self.text # Register model as snippet using register_snippet as both a function and a decorator class RegisterFunction(models.Model): pass register_snippet(RegisterFunction) @register_snippet class RegisterDecorator(models.Model): pass
rgb_value = [str(int(x, 16)) for x in split] rgb_string = ', '.join(rgb_value) return rgb_string def __str__(self): return self.name def save(self, *args, **kwargs): if not self.hex_value.startswith("#"): self.hex_value = "#{}".format(self.hex_value) super(Colour, self).save(*args, **kwargs) class Meta: ordering = ['name', ] register_snippet(Colour) @python_2_unicode_compatible class FontStyle(models.Model): name = models.CharField(max_length=1024) font_size = models.FloatField(default=1, help_text="The size of the fonts in ems.") line_size = models.FloatField(default=100, help_text="The line height as a percentage.") text_colour = models.ForeignKey( Colour, default=1, null=True, on_delete=models.SET_NULL ) panels = [
), ImageChooserPanel('image'), ] def __str__(self): return self.title @property def pages(self): return [ self.page_1, self.page_2, self.page_3, self.page_4, self.page_5, self.page_6, self.page_7, self.page_8 ] register_snippet(NavigationMenu) register_snippet(RSSImport) register_snippet(PageCollection) # Blocks class RSSImportBlock(core_blocks.StructBlock): feed = snippet_blocks.SnippetChooserBlock(required=True, target_model=RSSImport) class Meta: template = 'home/blocks/rss_import_block.html' icon = 'snippet' label = 'RSS Import'
from __future__ import absolute_import from twitter import models as twitter_models from wagtail.wagtailadmin.edit_handlers import FieldPanel from wagtail.wagtailsnippets.models import register_snippet register_snippet(twitter_models.User) twitter_models.User.panels = [ FieldPanel('screen_name'), FieldPanel('active'), ]
default = models.BooleanField(default=False) panels = [ FieldPanel('name'), FieldPanel('contact_email'), FieldPanel('default'), InlinePanel('block_links', label="Content Blocks"), InlinePanel('follow_links', label="Follow Links"), InlinePanel('logo_links', label="Logos"), ] def __str__(self): return self.name register_snippet(ThemeContent) @python_2_unicode_compatible class Theme(models.Model): name = models.CharField(max_length=1024) folder = models.CharField(max_length=1024, default="themes/default") content = models.ForeignKey(ThemeContent, null=True) def __str__(self): return self.name panels = [ FieldPanel('name'), FieldPanel('folder'), SnippetChooserPanel('content'),
from modelcluster.fields import ParentalKey class Developer(models.Model): name = models.CharField('Developer', max_length=50) about = RichTextField(blank=True, null=True) panels = [ FieldPanel('name', classname="full title"), FieldPanel('about', classname="full"), ] def __str__(self): return self.name register_snippet(Developer) class ImageFields(models.Model): image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ ImageChooserPanel('image'), ]
@python_2_unicode_compatible class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [ FieldPanel('url'), FieldPanel('text'), ] def __str__(self): return self.text register_snippet(Advert) class StandardIndex(Page): """ Index for the site, not allowed to be placed anywhere """ parent_page_types = [] # A custom panel setup where all Promote fields are placed in the Content tab instead; # we use this to test that the 'promote' tab is left out of the output when empty StandardIndex.content_panels = [ FieldPanel('title', classname="full title"), FieldPanel('seo_title'), FieldPanel('slug'), InlinePanel('advert_placements', label="Adverts"), ]
return self.get_blocks_of_type('related') @property def documents(self): return self.get_blocks_of_type('document') content_panels = Page.content_panels + [ FieldPanel('summary'), ImageChooserPanel('lead_art'), StreamFieldPanel('body'), ] promote_panels = Page.promote_panels + [ FieldPanel('featured'), FieldPanel('tags'), ] search_fields = Page.search_fields + TagSearchable.search_fields + ( index.SearchField('body', partial_match=True), ) @property def date(self): if not self.first_published_at: return None return self.first_published_at.date() class Meta: ordering = ['-first_published_at'] register_snippet(ExtraTag)
url = models.URLField(null=True, blank=True) text = models.CharField(max_length=191) tags = TaggableManager(through=AdvertTag, blank=True) panels = [ FieldPanel('url'), FieldPanel('text'), FieldPanel('tags'), ] def __str__(self): return self.text register_snippet(Advert) @python_2_unicode_compatible class AdvertWithTabbedInterface(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=191) something_else = models.CharField(max_length=191) advert_panels = [ FieldPanel('url'), FieldPanel('text'), ] other_panels = [ FieldPanel('something_else'),
panels = [ FieldPanel('title'), FieldPanel('url'), FieldPanel('text'), ImageChooserPanel('image'), ] class Meta: verbose_name = "LINK BLOCK- A link with an image." verbose_name_plural = "LINK BLOCKS - put your links here first. Then you can add them to pages or sections." def __unicode__(self): return self.title register_snippet(LinkBlock) class EnglishLinkBlockPlacement(models.Model): page = ParentalKey('demo.EnglishHomePage', related_name='linkblock_placements') linkBlock = models.ForeignKey('demo.LinkBlock', related_name='+') position = models.CharField(max_length=45, default="content-bottom", choices=POSITION_CHOICES, help_text="""Determines the postion of the link on the page or section.""") class Meta: verbose_name = "English Home Page Link" verbose_name_plural = "English Home Page Links" panels = [ PageChooserPanel('page', 'demo.EnglishHomePage'),
def setUp(self): register_snippet(ZuluSnippet) register_snippet(AlphaSnippet)
null=True, blank=True ) url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [ PageChooserPanel('page'), FieldPanel('url'), FieldPanel('text'), ] def __unicode__(self): return self.text register_snippet(Advert) # Custom image class TorchboxImage(AbstractImage): credit = models.CharField(max_length=255, blank=True) admin_form_fields = Image.admin_form_fields + ( 'credit', ) @property def credit_text(self): return self.credit
from wagtail.wagtailsnippets.models import register_snippet from oscar_wagtail.edit_handlers import ProductChooserPanel class ProductListSnippet(ClusterableModel): title = models.CharField(max_length=255) code = models.CharField(max_length=100, unique=True) panels = [ FieldPanel('title'), FieldPanel('code'), ] def __unicode__(self): return self.title class ProductListItem(Orderable): parent = ParentalKey(to=ProductListSnippet, related_name='items') product = models.ForeignKey('catalogue.Product', related_name='+') panels = [ ProductChooserPanel('product'), ] ProductListSnippet.panels += [InlinePanel('items', label=_("Products"))] register_snippet(ProductListSnippet)