mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-12 01:03:11 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
bb0039b29a
98 changed files with 3055 additions and 865 deletions
|
|
@ -39,6 +39,8 @@ Changelog
|
|||
* Date / time pickers now consistently use times without seconds, to prevent Javascript behaviour glitches when focusing / unfocusing fields
|
||||
* Added hooks `register_rich_text_embed_handler` and `register_rich_text_link_handler` for customising link / embed handling within rich text fields
|
||||
* Added hook `construct_homepage_summary_items` for customising the site summary panel on the admin homepage
|
||||
* No longer automatically tries to use Celery for sending notification emails
|
||||
* Added "Add child page" button to admin userbar (Eric Drechsel)
|
||||
|
||||
|
||||
0.8.6 (10.03.2015)
|
||||
|
|
|
|||
|
|
@ -28,21 +28,6 @@ We recommend `Redis <http://redis.io/>`_ as a fast, persistent cache. Install Re
|
|||
Without a persistent cache, Wagtail will recreate all compressable assets at each server start, e.g. when any files change under ``./manage.py runserver``.
|
||||
|
||||
|
||||
Sending emails in the background using Celery
|
||||
---------------------------------------------
|
||||
|
||||
Various actions in the Wagtail admin backend can trigger notification emails - for example, submitting a page for moderation. In Wagtail's default configuration, these are sent as part of the page request/response cycle, which means that web server threads can get tied up for long periods if many emails are being sent. To avoid this, Wagtail can be configured to do this as a background task, using `Celery <http://www.celeryproject.org/>`_ as a task queue. To install Celery, add ``django-celery`` to your requirements.txt. A sample configuration, using Redis as the queue backend, would look like::
|
||||
|
||||
import djcelery
|
||||
|
||||
djcelery.setup_loader()
|
||||
|
||||
CELERY_SEND_TASK_ERROR_EMAILS = True
|
||||
BROKER_URL = 'redis://'
|
||||
|
||||
See the Celery documentation for instructions on running the worker process in development or production.
|
||||
|
||||
|
||||
Search
|
||||
------
|
||||
|
||||
|
|
|
|||
|
|
@ -285,10 +285,10 @@ Any block type is valid as the sub-block type, including structural types:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
('ingredients_list', blocks.ListBlock(blocks.StructBlock(
|
||||
('ingredients_list', blocks.ListBlock(blocks.StructBlock([
|
||||
('ingredient', blocks.CharBlock(required=True)),
|
||||
('amount', blocks.CharBlock()),
|
||||
)))
|
||||
])))
|
||||
|
||||
|
||||
StreamBlock
|
||||
|
|
@ -305,9 +305,9 @@ A block consisting of a sequence of sub-blocks of different types, which can be
|
|||
('image', ImageChooserBlock()),
|
||||
('quotation', blocks.StructBlock([
|
||||
('text', blocks.TextBlock()),
|
||||
('author', blocks.CharBlock),
|
||||
('author', blocks.CharBlock()),
|
||||
])),
|
||||
('video', blocks.EmbedBlock()),
|
||||
('video', EmbedBlock()),
|
||||
],
|
||||
icon='cogs'
|
||||
))
|
||||
|
|
@ -321,9 +321,9 @@ As with StructBlock, the list of sub-blocks can also be provided as a subclass o
|
|||
image = ImageChooserBlock()
|
||||
quotation = blocks.StructBlock([
|
||||
('text', blocks.TextBlock()),
|
||||
('author', blocks.CharBlock),
|
||||
('author', blocks.CharBlock()),
|
||||
])
|
||||
video = blocks.EmbedBlock
|
||||
video = EmbedBlock()
|
||||
|
||||
class Meta:
|
||||
icon='cogs'
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ Admin
|
|||
* Added pagination to the snippets listing and chooser
|
||||
* Page / document / image / snippet choosers now include a link to edit the chosen item
|
||||
* Plain text fields in the page editor now use auto-expanding text areas
|
||||
* Added "Add child page" button to admin userbar
|
||||
|
||||
|
||||
**Page editor**
|
||||
|
|
@ -85,6 +86,7 @@ Project template
|
|||
|
||||
* The Vagrantfile now listens on port 8000
|
||||
* Removed ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` settings (as Wagtail no longer requires these)
|
||||
* Removed example Celery configuration from ``production.py`` and ``requirements.txt``
|
||||
|
||||
|
||||
Search
|
||||
|
|
@ -123,6 +125,17 @@ It is no longer necessary to pass the base model as a parameter, so this declara
|
|||
|
||||
The old format is now deprecated; all existing ``InlinePanel`` declarations should be updated to the new format.
|
||||
|
||||
Celery no longer automatically used for sending notification emails
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Previously, Wagtail would try to use Celery whenever the ``djcelery`` module was
|
||||
installed, even if Celery wasn't actually set up. This could cause a very hard
|
||||
to track down problem where notification emails would not be sent so this
|
||||
functionality has now been removed.
|
||||
|
||||
If you would like to keep using Celery for sending notification emails, have a
|
||||
look at: `django-celery-email <https://pypi.python.org/pypi/django-celery-email>`_
|
||||
|
||||
You no longer need ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` to point to Wagtail admin.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from django.db import models
|
||||
from django.apps import apps
|
||||
|
||||
from wagtail.wagtailcore.signals import page_published, page_unpublished
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ def page_unpublished_signal_handler(instance, **kwargs):
|
|||
|
||||
def register_signal_handlers():
|
||||
# Get list of models that are page types
|
||||
Page = models.get_model('wagtailcore', 'Page')
|
||||
indexed_models = [model for model in models.get_models() if issubclass(model, Page)]
|
||||
Page = apps.get_model('wagtailcore', 'Page')
|
||||
indexed_models = [model for model in apps.get_models() if issubclass(model, Page)]
|
||||
|
||||
# Loop through list and register signal handlers for each one
|
||||
for model in indexed_models:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.test import TestCase, RequestFactory
|
||||
|
||||
from wagtail.wagtailcore.models import Page, Site
|
||||
from wagtail.tests.models import RoutablePageTest, routable_page_external_view
|
||||
from wagtail.tests.routablepage.models import RoutablePageTest, routable_page_external_view
|
||||
from wagtail.contrib.wagtailroutablepage.templatetags.wagtailroutablepage_tags import routablepageurl
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.test import TestCase
|
|||
from django.core.cache import cache
|
||||
|
||||
from wagtail.wagtailcore.models import Page, PageViewRestriction, Site
|
||||
from wagtail.tests.models import SimplePage, EventIndex
|
||||
from wagtail.tests.testapp.models import SimplePage, EventIndex
|
||||
|
||||
from .sitemap_generator import Sitemap
|
||||
|
||||
|
|
|
|||
|
|
@ -13,19 +13,6 @@ TEMPLATE_DEBUG = False
|
|||
COMPRESS_OFFLINE = True
|
||||
|
||||
|
||||
# Send notification emails as a background task using Celery,
|
||||
# to prevent this from blocking web server threads
|
||||
# (requires the django-celery package):
|
||||
# http://celery.readthedocs.org/en/latest/configuration.html
|
||||
|
||||
# import djcelery
|
||||
#
|
||||
# djcelery.setup_loader()
|
||||
#
|
||||
# CELERY_SEND_TASK_ERROR_EMAILS = True
|
||||
# BROKER_URL = 'redis://'
|
||||
|
||||
|
||||
# Use Redis as the cache backend for extra performance
|
||||
# (requires the django-redis-cache package):
|
||||
# http://wagtail.readthedocs.org/en/latest/howto/performance.html#cache
|
||||
|
|
|
|||
|
|
@ -8,4 +8,3 @@ wagtail==1.0b1
|
|||
|
||||
# Recommended components to improve performance in production:
|
||||
# django-redis==3.8.2
|
||||
# django-celery==3.1.10
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('customuser', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='groups',
|
||||
field=models.ManyToManyField(to='auth.Group', verbose_name='groups', help_text='The groups this user belongs to. A user will get all permissions granted to each of his/her group.', related_name='user_set', blank=True, related_query_name='user'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='user_permissions',
|
||||
field=models.ManyToManyField(to='auth.Permission', verbose_name='user permissions', help_text='Specific permissions for this user.', related_name='user_set', blank=True, related_query_name='user'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/customuser/migrations/__init__.py
Normal file
0
wagtail/tests/customuser/migrations/__init__.py
Normal file
47
wagtail/tests/customuser/models.py
Normal file
47
wagtail/tests/customuser/models.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
from django.db import models
|
||||
|
||||
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
|
||||
|
||||
|
||||
class CustomUserManager(BaseUserManager):
|
||||
def _create_user(self, username, email, password,
|
||||
is_staff, is_superuser, **extra_fields):
|
||||
"""
|
||||
Creates and saves a User with the given username, email and password.
|
||||
"""
|
||||
if not username:
|
||||
raise ValueError('The given username must be set')
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(username=username, email=email,
|
||||
is_staff=is_staff, is_active=True,
|
||||
is_superuser=is_superuser, **extra_fields)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
def create_user(self, username, email=None, password=None, **extra_fields):
|
||||
return self._create_user(username, email, password, False, False,
|
||||
**extra_fields)
|
||||
|
||||
def create_superuser(self, username, email, password, **extra_fields):
|
||||
return self._create_user(username, email, password, True, True,
|
||||
**extra_fields)
|
||||
|
||||
|
||||
class CustomUser(AbstractBaseUser, PermissionsMixin):
|
||||
username = models.CharField(max_length=100, unique=True)
|
||||
email = models.EmailField(max_length=255, blank=True)
|
||||
is_staff = models.BooleanField(default=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
first_name = models.CharField(max_length=50, blank=True)
|
||||
last_name = models.CharField(max_length=50, blank=True)
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
|
||||
objects = CustomUserManager()
|
||||
|
||||
def get_full_name(self):
|
||||
return self.first_name + ' ' + self.last_name
|
||||
|
||||
def get_short_name(self):
|
||||
return self.first_name
|
||||
0
wagtail/tests/demosite/__init__.py
Normal file
0
wagtail/tests/demosite/__init__.py
Normal file
1150
wagtail/tests/demosite/fixtures/demosite.json
Normal file
1150
wagtail/tests/demosite/fixtures/demosite.json
Normal file
File diff suppressed because it is too large
Load diff
513
wagtail/tests/demosite/migrations/0001_initial.py
Normal file
513
wagtail/tests/demosite/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.db.models.deletion
|
||||
import modelcluster.tags
|
||||
import wagtail.wagtailcore.fields
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailimages', '0005_make_filter_spec_unique'),
|
||||
('taggit', '0001_initial'),
|
||||
('wagtaildocs', '0002_initial_data'),
|
||||
('wagtailcore', '0013_update_golive_expire_help_text'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BlogEntryPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField()),
|
||||
('date', models.DateField(verbose_name='Post date')),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BlogEntryPageCarouselItem',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('embed_url', models.URLField(blank=True, verbose_name='Embed URL')),
|
||||
('caption', models.CharField(blank=True, max_length=255)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BlogEntryPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BlogEntryPageTag',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('content_object', modelcluster.fields.ParentalKey(to='demosite.BlogEntryPage', related_name='tagged_items')),
|
||||
('tag', models.ForeignKey(to='taggit.Tag', related_name='demosite_blogentrypagetag_items')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BlogIndexPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BlogIndexPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ContactPage',
|
||||
fields=[
|
||||
('telephone', models.CharField(blank=True, max_length=20)),
|
||||
('email', models.EmailField(blank=True, max_length=75)),
|
||||
('address_1', models.CharField(blank=True, max_length=255)),
|
||||
('address_2', models.CharField(blank=True, max_length=255)),
|
||||
('city', models.CharField(blank=True, max_length=255)),
|
||||
('country', models.CharField(blank=True, max_length=255)),
|
||||
('post_code', models.CharField(blank=True, max_length=10)),
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page', models.Model),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventIndexPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventIndexPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('date_from', models.DateField(verbose_name='Start date')),
|
||||
('date_to', models.DateField(help_text='Not required if event is on a single day', null=True, verbose_name='End date', blank=True)),
|
||||
('time_from', models.TimeField(null=True, verbose_name='Start time', blank=True)),
|
||||
('time_to', models.TimeField(null=True, verbose_name='End time', blank=True)),
|
||||
('audience', models.CharField(choices=[('public', 'Public'), ('private', 'Private')], max_length=255)),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('cost', models.CharField(max_length=255)),
|
||||
('signup_link', models.URLField(blank=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageCarouselItem',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('embed_url', models.URLField(blank=True, verbose_name='Embed URL')),
|
||||
('caption', models.CharField(blank=True, max_length=255)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageSpeaker',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('first_name', models.CharField(blank=True, verbose_name='Name', max_length=255)),
|
||||
('last_name', models.CharField(blank=True, verbose_name='Surname', max_length=255)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HomePage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Homepage',
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HomePageCarouselItem',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('embed_url', models.URLField(blank=True, verbose_name='Embed URL')),
|
||||
('caption', models.CharField(blank=True, max_length=255)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HomePageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PersonPage',
|
||||
fields=[
|
||||
('telephone', models.CharField(blank=True, max_length=20)),
|
||||
('email', models.EmailField(blank=True, max_length=75)),
|
||||
('address_1', models.CharField(blank=True, max_length=255)),
|
||||
('address_2', models.CharField(blank=True, max_length=255)),
|
||||
('city', models.CharField(blank=True, max_length=255)),
|
||||
('country', models.CharField(blank=True, max_length=255)),
|
||||
('post_code', models.CharField(blank=True, max_length=10)),
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('first_name', models.CharField(max_length=255)),
|
||||
('last_name', models.CharField(max_length=255)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('biography', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page', models.Model),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PersonPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardIndexPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardIndexPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, parent_link=True, related_name='+', primary_key=True)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardPageCarouselItem',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('embed_url', models.URLField(blank=True, verbose_name='Embed URL')),
|
||||
('caption', models.CharField(blank=True, max_length=255)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', blank=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
('link_page', models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True)),
|
||||
('page', modelcluster.fields.ParentalKey(to='demosite.StandardPage', related_name='carousel_items')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('sort_order', models.IntegerField(null=True, editable=False, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', blank=True, related_name='+', null=True)),
|
||||
('link_page', models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True)),
|
||||
('page', modelcluster.fields.ParentalKey(to='demosite.StandardPage', related_name='related_links')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='standardindexpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='standardindexpagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.StandardIndexPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='personpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='personpagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.PersonPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='homepagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='homepagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.HomePage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='homepagecarouselitem',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='homepagecarouselitem',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.HomePage', related_name='carousel_items'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagespeaker',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagespeaker',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.EventPage', related_name='speakers'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.EventPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagecarouselitem',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventpagecarouselitem',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.EventPage', related_name='carousel_items'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventindexpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='eventindexpagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.EventIndexPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogindexpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogindexpagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.BlogIndexPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogentrypagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogentrypagerelatedlink',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.BlogEntryPage', related_name='related_links'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogentrypagecarouselitem',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', blank=True, related_name='+', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogentrypagecarouselitem',
|
||||
name='page',
|
||||
field=modelcluster.fields.ParentalKey(to='demosite.BlogEntryPage', related_name='carousel_items'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogentrypage',
|
||||
name='tags',
|
||||
field=modelcluster.tags.ClusterTaggableManager(help_text='A comma-separated list of tags.', through='demosite.BlogEntryPageTag', blank=True, verbose_name='Tags', to='taggit.Tag'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/demosite/migrations/__init__.py
Normal file
0
wagtail/tests/demosite/migrations/__init__.py
Normal file
594
wagtail/tests/demosite/models.py
Normal file
594
wagtail/tests/demosite/models.py
Normal file
|
|
@ -0,0 +1,594 @@
|
|||
from django.db import models
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
|
||||
from modelcluster.fields import ParentalKey
|
||||
from modelcluster.tags import ClusterTaggableManager
|
||||
from taggit.models import Tag, TaggedItemBase
|
||||
|
||||
from wagtail.wagtailcore.models import Page, Orderable
|
||||
from wagtail.wagtailcore.fields import RichTextField
|
||||
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, \
|
||||
InlinePanel, PageChooserPanel
|
||||
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
|
||||
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
|
||||
from wagtail.wagtailsnippets.models import register_snippet
|
||||
from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField
|
||||
from wagtail.wagtailsearch import index
|
||||
|
||||
|
||||
# ABSTRACT MODELS
|
||||
# =============================
|
||||
|
||||
class AbstractLinkFields(models.Model):
|
||||
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,
|
||||
blank=True,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
if self.link_page:
|
||||
return self.link_page.url
|
||||
elif self.link_document:
|
||||
return self.link_document.url
|
||||
else:
|
||||
return self.link_external
|
||||
|
||||
api_fields = ('link', )
|
||||
|
||||
panels = [
|
||||
FieldPanel('link_external'),
|
||||
PageChooserPanel('link_page'),
|
||||
DocumentChooserPanel('link_document'),
|
||||
]
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class AbstractRelatedLink(AbstractLinkFields):
|
||||
title = models.CharField(max_length=255, help_text="Link title")
|
||||
|
||||
api_fields = ('title', ) + AbstractLinkFields.api_fields
|
||||
|
||||
panels = [
|
||||
FieldPanel('title'),
|
||||
MultiFieldPanel(AbstractLinkFields.panels, "Link"),
|
||||
]
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class AbstractCarouselItem(AbstractLinkFields):
|
||||
image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
embed_url = models.URLField("Embed URL", blank=True)
|
||||
caption = models.CharField(max_length=255, blank=True)
|
||||
|
||||
api_fields = (
|
||||
'image',
|
||||
'embed_url',
|
||||
'caption',
|
||||
) + AbstractLinkFields.api_fields
|
||||
|
||||
panels = [
|
||||
ImageChooserPanel('image'),
|
||||
FieldPanel('embed_url'),
|
||||
FieldPanel('caption'),
|
||||
MultiFieldPanel(AbstractLinkFields.panels, "Link"),
|
||||
]
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class ContactFieldsMixin(models.Model):
|
||||
telephone = models.CharField(max_length=20, blank=True)
|
||||
email = models.EmailField(blank=True)
|
||||
address_1 = models.CharField(max_length=255, blank=True)
|
||||
address_2 = models.CharField(max_length=255, blank=True)
|
||||
city = models.CharField(max_length=255, blank=True)
|
||||
country = models.CharField(max_length=255, blank=True)
|
||||
post_code = models.CharField(max_length=10, blank=True)
|
||||
|
||||
api_fields = (
|
||||
'telephone',
|
||||
'email',
|
||||
'address_1',
|
||||
'address_2',
|
||||
'city',
|
||||
'country',
|
||||
'post_code',
|
||||
)
|
||||
|
||||
panels = [
|
||||
FieldPanel('telephone'),
|
||||
FieldPanel('email'),
|
||||
FieldPanel('address_1'),
|
||||
FieldPanel('address_2'),
|
||||
FieldPanel('city'),
|
||||
FieldPanel('country'),
|
||||
FieldPanel('post_code'),
|
||||
]
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
# PAGE MODELS
|
||||
# =============================
|
||||
|
||||
# Home page
|
||||
|
||||
class HomePage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
body = RichTextField(blank=True)
|
||||
|
||||
api_fields = (
|
||||
'body',
|
||||
'carousel_items',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('body'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Homepage"
|
||||
|
||||
|
||||
class HomePageCarouselItem(Orderable, AbstractCarouselItem):
|
||||
page = ParentalKey('HomePage', related_name='carousel_items')
|
||||
|
||||
class HomePageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('HomePage', related_name='related_links')
|
||||
|
||||
HomePage.content_panels = Page.content_panels + [
|
||||
FieldPanel('body', classname="full"),
|
||||
|
||||
InlinePanel(HomePage, 'carousel_items', label="Carousel items"),
|
||||
InlinePanel(HomePage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
|
||||
# Standard pages
|
||||
|
||||
class StandardPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
intro = RichTextField(blank=True)
|
||||
body = RichTextField(blank=True)
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'intro',
|
||||
'body',
|
||||
'feed_image',
|
||||
'carousel_items',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('intro'),
|
||||
index.SearchField('body'),
|
||||
)
|
||||
|
||||
class StandardPageCarouselItem(Orderable, AbstractCarouselItem):
|
||||
page = ParentalKey('StandardPage', related_name='carousel_items')
|
||||
|
||||
class StandardPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('StandardPage', related_name='related_links')
|
||||
|
||||
StandardPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('intro', classname="full"),
|
||||
InlinePanel(StandardPage, 'carousel_items', label="Carousel items"),
|
||||
FieldPanel('body', classname="full"),
|
||||
InlinePanel(StandardPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
StandardPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
]
|
||||
|
||||
|
||||
class StandardIndexPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
intro = RichTextField(blank=True)
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'intro',
|
||||
'feed_image',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('intro'),
|
||||
)
|
||||
|
||||
class StandardIndexPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('StandardIndexPage', related_name='related_links')
|
||||
|
||||
StandardIndexPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('intro', classname="full"),
|
||||
InlinePanel(StandardIndexPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
StandardIndexPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
]
|
||||
|
||||
|
||||
# Blog pages
|
||||
|
||||
class BlogEntryPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
body = RichTextField()
|
||||
tags = ClusterTaggableManager(through='BlogEntryPageTag', blank=True)
|
||||
date = models.DateField("Post date")
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'body',
|
||||
'tags',
|
||||
'date',
|
||||
'feed_image',
|
||||
'carousel_items',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('body'),
|
||||
)
|
||||
|
||||
def get_blog_index(self):
|
||||
# Find closest ancestor which is a blog index
|
||||
return BlogIndexPage.ancestor_of(self).last()
|
||||
|
||||
class BlogEntryPageCarouselItem(Orderable, AbstractCarouselItem):
|
||||
page = ParentalKey('BlogEntryPage', related_name='carousel_items')
|
||||
|
||||
class BlogEntryPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('BlogEntryPage', related_name='related_links')
|
||||
|
||||
class BlogEntryPageTag(TaggedItemBase):
|
||||
content_object = ParentalKey('BlogEntryPage', related_name='tagged_items')
|
||||
|
||||
BlogEntryPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('date'),
|
||||
FieldPanel('body', classname="full"),
|
||||
InlinePanel(BlogEntryPage, 'carousel_items', label="Carousel items"),
|
||||
InlinePanel(BlogEntryPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
BlogEntryPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
FieldPanel('tags'),
|
||||
]
|
||||
|
||||
|
||||
class BlogIndexPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
intro = RichTextField(blank=True)
|
||||
|
||||
api_fields = (
|
||||
'intro',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('intro'),
|
||||
)
|
||||
|
||||
def get_blog_entries(self):
|
||||
# Get list of live blog pages that are descendants of this page
|
||||
entries = BlogEntryPage.objects.descendant_of(self).live()
|
||||
|
||||
# Order by most recent date first
|
||||
entries = entries.order_by('-date')
|
||||
|
||||
return entries
|
||||
|
||||
def get_context(self, request):
|
||||
# Get blog entries
|
||||
entries = self.get_blog_entries()
|
||||
|
||||
# Filter by tag
|
||||
tag = request.GET.get('tag')
|
||||
if tag:
|
||||
entries = entries.filter(tags__name=tag)
|
||||
|
||||
# Pagination
|
||||
page = request.GET.get('page')
|
||||
paginator = Paginator(entries, 10) # Show 10 entries per page
|
||||
try:
|
||||
entries = paginator.page(page)
|
||||
except PageNotAnInteger:
|
||||
entries = paginator.page(1)
|
||||
except EmptyPage:
|
||||
entries = paginator.page(paginator.num_pages)
|
||||
|
||||
# Update template context
|
||||
context = super(BlogIndexPage, self).get_context(request)
|
||||
context['entries'] = entries
|
||||
return context
|
||||
|
||||
class BlogIndexPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('BlogIndexPage', related_name='related_links')
|
||||
|
||||
BlogIndexPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('intro', classname="full"),
|
||||
InlinePanel(BlogIndexPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
|
||||
# Events pages
|
||||
|
||||
class EventPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
AUDIENCE_CHOICES = (
|
||||
('public', "Public"),
|
||||
('private', "Private"),
|
||||
)
|
||||
|
||||
date_from = models.DateField("Start date")
|
||||
date_to = models.DateField(
|
||||
"End date",
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="Not required if event is on a single day"
|
||||
)
|
||||
time_from = models.TimeField("Start time", null=True, blank=True)
|
||||
time_to = models.TimeField("End time", null=True, blank=True)
|
||||
audience = models.CharField(max_length=255, choices=AUDIENCE_CHOICES)
|
||||
location = models.CharField(max_length=255)
|
||||
body = RichTextField(blank=True)
|
||||
cost = models.CharField(max_length=255)
|
||||
signup_link = models.URLField(blank=True)
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'date_from',
|
||||
'date_to',
|
||||
'time_from',
|
||||
'time_to',
|
||||
'audience',
|
||||
'location',
|
||||
'body',
|
||||
'cost',
|
||||
'signup_link',
|
||||
'feed_image',
|
||||
'carousel_items',
|
||||
'related_links',
|
||||
'speakers',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('get_audience_display'),
|
||||
index.SearchField('location'),
|
||||
index.SearchField('body'),
|
||||
)
|
||||
|
||||
def get_event_index(self):
|
||||
# Find closest ancestor which is an event index
|
||||
return EventIndexPage.objects.ancester_of(self).last()
|
||||
|
||||
class EventPageCarouselItem(Orderable, AbstractCarouselItem):
|
||||
page = ParentalKey('EventPage', related_name='carousel_items')
|
||||
|
||||
class EventPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('EventPage', related_name='related_links')
|
||||
|
||||
class EventPageSpeaker(Orderable, AbstractLinkFields):
|
||||
page = ParentalKey('EventPage', related_name='speakers')
|
||||
first_name = models.CharField("Name", max_length=255, blank=True)
|
||||
last_name = models.CharField("Surname", max_length=255, blank=True)
|
||||
image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'first_name',
|
||||
'last_name',
|
||||
'image',
|
||||
)
|
||||
|
||||
panels = [
|
||||
FieldPanel('first_name'),
|
||||
FieldPanel('last_name'),
|
||||
ImageChooserPanel('image'),
|
||||
MultiFieldPanel(AbstractLinkFields.panels, "Link"),
|
||||
]
|
||||
|
||||
EventPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('date_from'),
|
||||
FieldPanel('date_to'),
|
||||
FieldPanel('time_from'),
|
||||
FieldPanel('time_to'),
|
||||
FieldPanel('location'),
|
||||
FieldPanel('audience'),
|
||||
FieldPanel('cost'),
|
||||
FieldPanel('signup_link'),
|
||||
InlinePanel(EventPage, 'carousel_items', label="Carousel items"),
|
||||
FieldPanel('body', classname="full"),
|
||||
InlinePanel(EventPage, 'speakers', label="Speakers"),
|
||||
InlinePanel(EventPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
EventPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
]
|
||||
|
||||
|
||||
class EventIndexPage(Page):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
intro = RichTextField(blank=True)
|
||||
|
||||
api_fields = (
|
||||
'intro',
|
||||
'related_links',
|
||||
)
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('intro'),
|
||||
)
|
||||
|
||||
def get_events(self):
|
||||
# Get list of live event pages that are descendants of this page
|
||||
events = EventPage.objects.descendant_of(self).live()
|
||||
|
||||
# Filter events list to get ones that are either
|
||||
# running now or start in the future
|
||||
events = events.filter(date_from__gte=date.today())
|
||||
|
||||
# Order by date
|
||||
events = events.order_by('date_from')
|
||||
|
||||
return events
|
||||
|
||||
class EventIndexPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('EventIndexPage', related_name='related_links')
|
||||
|
||||
EventIndexPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('intro', classname="full"),
|
||||
InlinePanel(EventIndexPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
|
||||
# Person page
|
||||
|
||||
class PersonPage(Page, ContactFieldsMixin):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
first_name = models.CharField(max_length=255)
|
||||
last_name = models.CharField(max_length=255)
|
||||
intro = RichTextField(blank=True)
|
||||
biography = RichTextField(blank=True)
|
||||
image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'first_name',
|
||||
'last_name',
|
||||
'intro',
|
||||
'biography',
|
||||
'image',
|
||||
'feed_image',
|
||||
'related_links',
|
||||
) + ContactFieldsMixin.api_fields
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('first_name'),
|
||||
index.SearchField('last_name'),
|
||||
index.SearchField('intro'),
|
||||
index.SearchField('biography'),
|
||||
)
|
||||
|
||||
class PersonPageRelatedLink(Orderable, AbstractRelatedLink):
|
||||
page = ParentalKey('PersonPage', related_name='related_links')
|
||||
|
||||
PersonPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('first_name'),
|
||||
FieldPanel('last_name'),
|
||||
FieldPanel('intro', classname="full"),
|
||||
FieldPanel('biography', classname="full"),
|
||||
ImageChooserPanel('image'),
|
||||
MultiFieldPanel(ContactFieldsMixin.panels, "Contact"),
|
||||
InlinePanel(PersonPage, 'related_links', label="Related links"),
|
||||
]
|
||||
|
||||
PersonPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
]
|
||||
|
||||
|
||||
# Contact page
|
||||
|
||||
class ContactPage(Page, ContactFieldsMixin):
|
||||
page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
|
||||
body = RichTextField(blank=True)
|
||||
feed_image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
api_fields = (
|
||||
'body',
|
||||
'feed_image',
|
||||
) + ContactFieldsMixin.api_fields
|
||||
|
||||
search_fields = Page.search_fields + (
|
||||
index.SearchField('body'),
|
||||
)
|
||||
|
||||
ContactPage.content_panels = Page.content_panels + [
|
||||
FieldPanel('body', classname="full"),
|
||||
MultiFieldPanel(ContactFieldsMixin.panels, "Contact"),
|
||||
]
|
||||
|
||||
ContactPage.promote_panels = [
|
||||
MultiFieldPanel(Page.promote_panels, "Common page configuration"),
|
||||
ImageChooserPanel('feed_image'),
|
||||
]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0002_auto_20140827_0908'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='advertplacement',
|
||||
name='colour',
|
||||
field=models.CharField(default='blue', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0003_auto_20140905_0634'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='SearchTestOldConfig',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='SearchTestOldConfigList',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0002_initial_data'),
|
||||
('tests', '0004_auto_20141008_0420'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PageChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page', models.ForeignKey(help_text=b'help text', to='wagtailcore.Page')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SnippetChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('advert', models.ForeignKey(help_text=b'help text', to='tests.Advert')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0002_initial_data'),
|
||||
('tests', '0004_auto_20141008_0420'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='formfield',
|
||||
name='choices',
|
||||
field=models.CharField(help_text='Comma separated list of choices. Only applicable in checkboxes, radio and dropdown.', max_length=512, blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='formfield',
|
||||
name='default_value',
|
||||
field=models.CharField(help_text='Default value. Comma separated values supported for checkboxes.', max_length=255, blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0005_auto_20141113_0642'),
|
||||
('tests', '0005_auto_20141008_0122'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0006_merge'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pagechoosermodel',
|
||||
name='page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', help_text='help text'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='snippetchoosermodel',
|
||||
name='advert',
|
||||
field=models.ForeignKey(to='tests.Advert', help_text='help text'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0007_auto_20141118_0925'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RegisterDecorator',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RegisterFunction',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0008_registerdecorator'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EventPageChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page', models.ForeignKey(help_text='more help text', to='tests.EventPage')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import wagtail.wagtailadmin.taggable
|
||||
from django.conf import settings
|
||||
import taggit.managers
|
||||
import wagtail.wagtailimages.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('taggit', '0001_initial'),
|
||||
('tests', '0009_eventpagechoosermodel'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CustomImageWithAdminFormFields',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
('title', models.CharField(verbose_name='Title', max_length=255)),
|
||||
('file', models.ImageField(verbose_name='File', height_field='height', upload_to=wagtail.wagtailimages.models.get_upload_to, width_field='width')),
|
||||
('width', models.IntegerField(editable=False)),
|
||||
('height', models.IntegerField(editable=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('focal_point_x', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_y', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('caption', models.CharField(max_length=255)),
|
||||
('not_editable_field', models.CharField(max_length=255)),
|
||||
('tags', taggit.managers.TaggableManager(verbose_name='Tags', help_text=None, through='taggit.TaggedItem', blank=True, to='taggit.Tag')),
|
||||
('uploaded_by_user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, blank=True, editable=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailadmin.taggable.TagSearchable),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomImageWithoutAdminFormFields',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
('title', models.CharField(verbose_name='Title', max_length=255)),
|
||||
('file', models.ImageField(verbose_name='File', height_field='height', upload_to=wagtail.wagtailimages.models.get_upload_to, width_field='width')),
|
||||
('width', models.IntegerField(editable=False)),
|
||||
('height', models.IntegerField(editable=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('focal_point_x', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_y', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('caption', models.CharField(max_length=255)),
|
||||
('not_editable_field', models.CharField(max_length=255)),
|
||||
('tags', taggit.managers.TaggableManager(verbose_name='Tags', help_text=None, through='taggit.TaggedItem', blank=True, to='taggit.Tag')),
|
||||
('uploaded_by_user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, blank=True, editable=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailadmin.taggable.TagSearchable),
|
||||
),
|
||||
]
|
||||
1
wagtail/tests/routablepage/__init__.py
Normal file
1
wagtail/tests/routablepage/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'wagtail.tests.routablepage.apps.WagtailRoutablePageTestsAppConfig'
|
||||
7
wagtail/tests/routablepage/apps.py
Normal file
7
wagtail/tests/routablepage/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WagtailRoutablePageTestsAppConfig(AppConfig):
|
||||
name = 'wagtail.tests.routablepage'
|
||||
label = 'routablepagetests'
|
||||
verbose_name = "Wagtail routable page tests"
|
||||
25
wagtail/tests/routablepage/migrations/0001_initial.py
Normal file
25
wagtail/tests/routablepage/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import wagtail.contrib.wagtailroutablepage.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0013_update_golive_expire_help_text'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RoutablePageTest',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True, parent_link=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(wagtail.contrib.wagtailroutablepage.models.RoutablePageMixin, 'wagtailcore.page'),
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/routablepage/migrations/__init__.py
Normal file
0
wagtail/tests/routablepage/migrations/__init__.py
Normal file
28
wagtail/tests/routablepage/models.py
Normal file
28
wagtail/tests/routablepage/models.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from django.db import models
|
||||
from django.http import HttpResponse
|
||||
from django.conf.urls import url
|
||||
|
||||
from wagtail.contrib.wagtailroutablepage.models import RoutablePage
|
||||
|
||||
|
||||
def routable_page_external_view(request, arg):
|
||||
return HttpResponse("EXTERNAL VIEW: " + arg)
|
||||
|
||||
class RoutablePageTest(RoutablePage):
|
||||
@property
|
||||
def subpage_urls(self):
|
||||
return (
|
||||
url(r'^$', self.main, name='main'),
|
||||
url(r'^archive/year/(\d+)/$', self.archive_by_year, name='archive_by_year'),
|
||||
url(r'^archive/author/(?P<author_slug>.+)/$', self.archive_by_author, name='archive_by_author'),
|
||||
url(r'^external/(.+)/$', routable_page_external_view, name='external_view')
|
||||
)
|
||||
|
||||
def archive_by_year(self, request, year):
|
||||
return HttpResponse("ARCHIVE BY YEAR: " + str(year))
|
||||
|
||||
def archive_by_author(self, request, author_slug):
|
||||
return HttpResponse("ARCHIVE BY AUTHOR: " + author_slug)
|
||||
|
||||
def main(self, request):
|
||||
return HttpResponse("MAIN VIEW")
|
||||
1
wagtail/tests/search/__init__.py
Normal file
1
wagtail/tests/search/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'wagtail.tests.search.apps.WagtailSearchTestsAppConfig'
|
||||
7
wagtail/tests/search/apps.py
Normal file
7
wagtail/tests/search/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WagtailSearchTestsAppConfig(AppConfig):
|
||||
name = 'wagtail.tests.search'
|
||||
label = 'searchtests'
|
||||
verbose_name = "Wagtail search tests"
|
||||
38
wagtail/tests/search/migrations/0001_initial.py
Normal file
38
wagtail/tests/search/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import wagtail.wagtailsearch.index
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SearchTest',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('content', models.TextField()),
|
||||
('live', models.BooleanField(default=False)),
|
||||
('published_date', models.DateField(null=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SearchTestChild',
|
||||
fields=[
|
||||
('searchtest_ptr', models.OneToOneField(primary_key=True, serialize=False, parent_link=True, to='searchtests.SearchTest', auto_created=True)),
|
||||
('subtitle', models.CharField(null=True, max_length=255, blank=True)),
|
||||
('extra_content', models.TextField()),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=('searchtests.searchtest',),
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/search/migrations/__init__.py
Normal file
0
wagtail/tests/search/migrations/__init__.py
Normal file
54
wagtail/tests/search/models.py
Normal file
54
wagtail/tests/search/models.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
from django.db import models
|
||||
|
||||
from wagtail.wagtailsearch import index
|
||||
|
||||
|
||||
class SearchTest(models.Model, index.Indexed):
|
||||
title = models.CharField(max_length=255)
|
||||
content = models.TextField()
|
||||
live = models.BooleanField(default=False)
|
||||
published_date = models.DateField(null=True)
|
||||
|
||||
search_fields = [
|
||||
index.SearchField('title', partial_match=True),
|
||||
index.SearchField('content'),
|
||||
index.SearchField('callable_indexed_field'),
|
||||
index.FilterField('title'),
|
||||
index.FilterField('live'),
|
||||
index.FilterField('published_date'),
|
||||
]
|
||||
|
||||
def callable_indexed_field(self):
|
||||
return "Callable"
|
||||
|
||||
@classmethod
|
||||
def get_indexed_objects(cls):
|
||||
indexed_objects = super(SearchTest, cls).get_indexed_objects()
|
||||
|
||||
# Exclude SearchTests that have a SearchTestChild to stop update_index creating duplicates
|
||||
if cls is SearchTest:
|
||||
indexed_objects = indexed_objects.exclude(
|
||||
id__in=SearchTestChild.objects.all().values_list('searchtest_ptr_id', flat=True)
|
||||
)
|
||||
|
||||
# Exclude SearchTests that have the title "Don't index me!"
|
||||
indexed_objects = indexed_objects.exclude(title="Don't index me!")
|
||||
|
||||
return indexed_objects
|
||||
|
||||
def get_indexed_instance(self):
|
||||
# Check if there is a SearchTestChild that descends from this
|
||||
child = SearchTestChild.objects.filter(searchtest_ptr_id=self.id).first()
|
||||
|
||||
# Return the child if there is one, otherwise return self
|
||||
return child or self
|
||||
|
||||
|
||||
class SearchTestChild(SearchTest):
|
||||
subtitle = models.CharField(max_length=255, null=True, blank=True)
|
||||
extra_content = models.TextField()
|
||||
|
||||
search_fields = SearchTest.search_fields + [
|
||||
index.SearchField('subtitle', partial_match=True),
|
||||
index.SearchField('extra_content'),
|
||||
]
|
||||
|
|
@ -76,7 +76,12 @@ INSTALLED_APPS = (
|
|||
'wagtail.contrib.wagtailsitemaps',
|
||||
'wagtail.contrib.wagtailroutablepage',
|
||||
'wagtail.contrib.wagtailfrontendcache',
|
||||
'wagtail.tests',
|
||||
'wagtail.tests.testapp',
|
||||
'wagtail.tests.demosite',
|
||||
'wagtail.tests.customuser',
|
||||
'wagtail.tests.snippets',
|
||||
'wagtail.tests.routablepage',
|
||||
'wagtail.tests.search',
|
||||
|
||||
# Install wagtailredirects with its appconfig
|
||||
# Theres nothing special about wagtailredirects, we just need to have one
|
||||
|
|
@ -110,7 +115,7 @@ WAGTAILSEARCH_BACKENDS = {
|
|||
}
|
||||
}
|
||||
|
||||
AUTH_USER_MODEL = 'tests.CustomUser'
|
||||
AUTH_USER_MODEL = 'customuser.CustomUser'
|
||||
|
||||
try:
|
||||
# Only add Elasticsearch backend if the elasticsearch-py library is installed
|
||||
|
|
|
|||
1
wagtail/tests/snippets/__init__.py
Normal file
1
wagtail/tests/snippets/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'wagtail.tests.snippets.apps.WagtailSnippetsTestsAppConfig'
|
||||
7
wagtail/tests/snippets/apps.py
Normal file
7
wagtail/tests/snippets/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WagtailSnippetsTestsAppConfig(AppConfig):
|
||||
name = 'wagtail.tests.snippets'
|
||||
label = 'snippetstests'
|
||||
verbose_name = "Wagtail snippets tests"
|
||||
51
wagtail/tests/snippets/migrations/0001_initial.py
Normal file
51
wagtail/tests/snippets/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AlphaSnippet',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RegisterDecorator',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RegisterFunction',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ZuluSnippet',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/snippets/migrations/__init__.py
Normal file
0
wagtail/tests/snippets/migrations/__init__.py
Normal file
39
wagtail/tests/snippets/models.py
Normal file
39
wagtail/tests/snippets/models.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from wagtail.wagtailsnippets.models import register_snippet
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
{% include "tests/includes/event_listing.html" %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Event: {{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
<h2>Event</h2>
|
||||
{% if self.feed_image %}
|
||||
{% image self.feed_image width-200 class="feed-image" %}
|
||||
{% endif %}
|
||||
{{ self.body|richtext }}
|
||||
<p><a href="{% slugurl 'events' %}">Back to events index</a></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
<p>This event is invitation only. Please enter your password to see the details.</p>
|
||||
<form action="{{ action_url }}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Continue" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{% load wagtailcore_tags %}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
<form action="{% pageurl self %}" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{% load wagtailcore_tags %}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
<p>Thank you for your feedback.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{% load wagtailcore_tags %}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ self.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ self.title }}</h1>
|
||||
<h2>Simple page</h2>
|
||||
</body>
|
||||
</html>
|
||||
1
wagtail/tests/testapp/__init__.py
Normal file
1
wagtail/tests/testapp/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'wagtail.tests.testapp.apps.WagtailTestsAppConfig'
|
||||
7
wagtail/tests/testapp/apps.py
Normal file
7
wagtail/tests/testapp/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WagtailTestsAppConfig(AppConfig):
|
||||
name = 'wagtail.tests.testapp'
|
||||
label = 'tests'
|
||||
verbose_name = "Wagtail tests"
|
||||
|
|
@ -461,7 +461,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "superuser",
|
||||
"first_name": "",
|
||||
|
|
@ -478,7 +478,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "eventeditor",
|
||||
"first_name": "",
|
||||
|
|
@ -496,7 +496,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "eventmoderator",
|
||||
"first_name": "",
|
||||
|
|
@ -514,7 +514,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "inactiveuser",
|
||||
"first_name": "",
|
||||
|
|
@ -532,7 +532,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "siteeditor",
|
||||
"first_name": "",
|
||||
|
|
@ -550,7 +550,7 @@
|
|||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "tests.customuser",
|
||||
"model": "customuser.customuser",
|
||||
"fields": {
|
||||
"username": "admin_only_user",
|
||||
"first_name": "",
|
||||
|
|
@ -3,29 +3,31 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import models, migrations
|
||||
import django.db.models.deletion
|
||||
import modelcluster.fields
|
||||
import wagtail.contrib.wagtailroutablepage.models
|
||||
import wagtail.wagtailcore.fields
|
||||
import wagtail.wagtailsearch.index
|
||||
from django.conf import settings
|
||||
import modelcluster.tags
|
||||
import wagtail.wagtailimages.models
|
||||
import wagtail.wagtailadmin.taggable
|
||||
import modelcluster.fields
|
||||
import wagtail.wagtailcore.fields
|
||||
import taggit.managers
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailcore', '0002_initial_data'),
|
||||
('wagtailcore', '0013_update_golive_expire_help_text'),
|
||||
('wagtaildocs', '0002_initial_data'),
|
||||
('taggit', '0001_initial'),
|
||||
('wagtailimages', '0002_initial_data'),
|
||||
('tests', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('wagtailimages', '0005_make_filter_spec_unique'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Advert',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('url', models.URLField(null=True, blank=True)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('url', models.URLField(blank=True, null=True)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
|
|
@ -35,27 +37,18 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='AdvertPlacement',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('colour', models.CharField(max_length=255)),
|
||||
('advert', models.ForeignKey(to='tests.Advert', related_name='+')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AlphaSnippet',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BusinessChild',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -65,7 +58,7 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='BusinessIndex',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -75,17 +68,63 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='BusinessSubIndex',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomImageWithAdminFormFields',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('title', models.CharField(max_length=255, verbose_name='Title')),
|
||||
('file', models.ImageField(width_field='width', height_field='height', upload_to=wagtail.wagtailimages.models.get_upload_to, verbose_name='File')),
|
||||
('width', models.IntegerField(editable=False)),
|
||||
('height', models.IntegerField(editable=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('focal_point_x', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_y', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('caption', models.CharField(max_length=255)),
|
||||
('not_editable_field', models.CharField(max_length=255)),
|
||||
('tags', taggit.managers.TaggableManager(verbose_name='Tags', to='taggit.Tag', blank=True, through='taggit.TaggedItem', help_text=None)),
|
||||
('uploaded_by_user', models.ForeignKey(null=True, blank=True, to=settings.AUTH_USER_MODEL, editable=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailadmin.taggable.TagSearchable),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomImageWithoutAdminFormFields',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('title', models.CharField(max_length=255, verbose_name='Title')),
|
||||
('file', models.ImageField(width_field='width', height_field='height', upload_to=wagtail.wagtailimages.models.get_upload_to, verbose_name='File')),
|
||||
('width', models.IntegerField(editable=False)),
|
||||
('height', models.IntegerField(editable=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('focal_point_x', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_y', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('focal_point_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('caption', models.CharField(max_length=255)),
|
||||
('not_editable_field', models.CharField(max_length=255)),
|
||||
('tags', taggit.managers.TaggableManager(verbose_name='Tags', to='taggit.Tag', blank=True, through='taggit.TaggedItem', help_text=None)),
|
||||
('uploaded_by_user', models.ForeignKey(null=True, blank=True, to=settings.AUTH_USER_MODEL, editable=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailadmin.taggable.TagSearchable),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventIndex',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
('intro', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
],
|
||||
options={
|
||||
|
|
@ -96,17 +135,17 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='EventPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('date_from', models.DateField(null=True, verbose_name='Start date')),
|
||||
('date_to', models.DateField(null=True, help_text='Not required if event is on a single day', blank=True, verbose_name='End date')),
|
||||
('time_from', models.TimeField(null=True, blank=True, verbose_name='Start time')),
|
||||
('time_to', models.TimeField(null=True, blank=True, verbose_name='End time')),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
('date_from', models.DateField(verbose_name='Start date', null=True)),
|
||||
('date_to', models.DateField(blank=True, help_text='Not required if event is on a single day', verbose_name='End date', null=True)),
|
||||
('time_from', models.TimeField(blank=True, verbose_name='Start time', null=True)),
|
||||
('time_to', models.TimeField(blank=True, verbose_name='End time', null=True)),
|
||||
('audience', models.CharField(choices=[('public', 'Public'), ('private', 'Private')], max_length=255)),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('body', wagtail.wagtailcore.fields.RichTextField(blank=True)),
|
||||
('cost', models.CharField(max_length=255)),
|
||||
('signup_link', models.URLField(blank=True)),
|
||||
('feed_image', models.ForeignKey(related_name='+', blank=True, to='wagtailimages.Image', on_delete=django.db.models.deletion.SET_NULL, null=True)),
|
||||
('feed_image', models.ForeignKey(to='wagtailimages.Image', null=True, related_name='+', blank=True, on_delete=django.db.models.deletion.SET_NULL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -116,74 +155,84 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='EventPageCarouselItem',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('sort_order', models.IntegerField(null=True, blank=True, editable=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('sort_order', models.IntegerField(editable=False, null=True, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('embed_url', models.URLField(blank=True, verbose_name='Embed URL')),
|
||||
('caption', models.CharField(blank=True, max_length=255)),
|
||||
('image', models.ForeignKey(related_name='+', blank=True, to='wagtailimages.Image', on_delete=django.db.models.deletion.SET_NULL, null=True)),
|
||||
('link_document', models.ForeignKey(related_name='+', blank=True, to='wagtaildocs.Document', null=True)),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', null=True, related_name='+', blank=True, on_delete=django.db.models.deletion.SET_NULL)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', null=True, related_name='+', blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('page', models.ForeignKey(to='tests.EventPage', help_text='more help text')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageRelatedLink',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('sort_order', models.IntegerField(null=True, blank=True, editable=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('sort_order', models.IntegerField(editable=False, null=True, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('title', models.CharField(help_text='Link title', max_length=255)),
|
||||
('link_document', models.ForeignKey(related_name='+', blank=True, to='wagtaildocs.Document', null=True)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', null=True, related_name='+', blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPageSpeaker',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('sort_order', models.IntegerField(null=True, blank=True, editable=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('sort_order', models.IntegerField(editable=False, null=True, blank=True)),
|
||||
('link_external', models.URLField(blank=True, verbose_name='External link')),
|
||||
('first_name', models.CharField(blank=True, verbose_name='Name', max_length=255)),
|
||||
('last_name', models.CharField(blank=True, verbose_name='Surname', max_length=255)),
|
||||
('image', models.ForeignKey(related_name='+', blank=True, to='wagtailimages.Image', on_delete=django.db.models.deletion.SET_NULL, null=True)),
|
||||
('link_document', models.ForeignKey(related_name='+', blank=True, to='wagtaildocs.Document', null=True)),
|
||||
('first_name', models.CharField(blank=True, max_length=255, verbose_name='Name')),
|
||||
('last_name', models.CharField(blank=True, max_length=255, verbose_name='Surname')),
|
||||
('image', models.ForeignKey(to='wagtailimages.Image', null=True, related_name='+', blank=True, on_delete=django.db.models.deletion.SET_NULL)),
|
||||
('link_document', models.ForeignKey(to='wagtaildocs.Document', null=True, related_name='+', blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormField',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('sort_order', models.IntegerField(null=True, blank=True, editable=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('sort_order', models.IntegerField(editable=False, null=True, blank=True)),
|
||||
('label', models.CharField(help_text='The label of the form field', max_length=255)),
|
||||
('field_type', models.CharField(choices=[('singleline', 'Single line text'), ('multiline', 'Multi-line text'), ('email', 'Email'), ('number', 'Number'), ('url', 'URL'), ('checkbox', 'Checkbox'), ('checkboxes', 'Checkboxes'), ('dropdown', 'Drop down'), ('radio', 'Radio buttons'), ('date', 'Date'), ('datetime', 'Date/time')], max_length=16)),
|
||||
('required', models.BooleanField(default=True)),
|
||||
('choices', models.CharField(blank=True, help_text='Comma seperated list of choices. Only applicable in checkboxes, radio and dropdown.', max_length=512)),
|
||||
('default_value', models.CharField(blank=True, help_text='Default value. Comma seperated values supported for checkboxes.', max_length=255)),
|
||||
('choices', models.CharField(blank=True, help_text='Comma separated list of choices. Only applicable in checkboxes, radio and dropdown.', max_length=512)),
|
||||
('default_value', models.CharField(blank=True, help_text='Default value. Comma separated values supported for checkboxes.', max_length=255)),
|
||||
('help_text', models.CharField(blank=True, max_length=255)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
('to_address', models.CharField(blank=True, help_text='Optional - form submissions will be emailed to this address', max_length=255)),
|
||||
('from_address', models.CharField(blank=True, max_length=255)),
|
||||
('subject', models.CharField(blank=True, max_length=255)),
|
||||
|
|
@ -193,10 +242,19 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PageChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PageWithOldStyleRouteMethod',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
('content', models.TextField()),
|
||||
],
|
||||
options={
|
||||
|
|
@ -204,62 +262,10 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RoutablePageTest',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(wagtail.contrib.wagtailroutablepage.models.RoutablePageMixin, 'wagtailcore.page'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SearchTest',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('content', models.TextField()),
|
||||
('live', models.BooleanField(default=False)),
|
||||
('published_date', models.DateField(null=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SearchTestChild',
|
||||
fields=[
|
||||
('searchtest_ptr', models.OneToOneField(parent_link=True, to='tests.SearchTest', serialize=False, auto_created=True, primary_key=True)),
|
||||
('subtitle', models.CharField(null=True, blank=True, max_length=255)),
|
||||
('extra_content', models.TextField()),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=('tests.searchtest',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SearchTestOldConfig',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SearchTestOldConfigList',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SimplePage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
('content', models.TextField()),
|
||||
],
|
||||
options={
|
||||
|
|
@ -267,10 +273,20 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SnippetChooserModel',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('advert', models.ForeignKey(to='tests.Advert', help_text='help text')),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StandardChild',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -280,7 +296,7 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='StandardIndex',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -290,7 +306,7 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='TaggedPage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(parent_link=True, to='wagtailcore.Page', serialize=False, auto_created=True, primary_key=True)),
|
||||
('page_ptr', models.OneToOneField(parent_link=True, primary_key=True, to='wagtailcore.Page', auto_created=True, serialize=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -300,7 +316,7 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='TaggedPageTag',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
|
||||
('content_object', modelcluster.fields.ParentalKey(to='tests.TaggedPage', related_name='tagged_items')),
|
||||
('tag', models.ForeignKey(to='taggit.Tag', related_name='tests_taggedpagetag_items')),
|
||||
],
|
||||
|
|
@ -309,20 +325,16 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ZuluSnippet',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='taggedpage',
|
||||
name='tags',
|
||||
field=modelcluster.tags.ClusterTaggableManager(through='tests.TaggedPageTag', blank=True, verbose_name='Tags', to='taggit.Tag', help_text='A comma-separated list of tags.'),
|
||||
field=modelcluster.tags.ClusterTaggableManager(verbose_name='Tags', to='taggit.Tag', blank=True, through='tests.TaggedPageTag', help_text='A comma-separated list of tags.'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='pagechoosermodel',
|
||||
name='page',
|
||||
field=models.ForeignKey(to='wagtailcore.Page', help_text='help text'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
|
|
@ -334,7 +346,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='eventpagespeaker',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(related_name='+', blank=True, to='wagtailcore.Page', null=True),
|
||||
field=models.ForeignKey(to='wagtailcore.Page', null=True, related_name='+', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
|
|
@ -346,7 +358,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='eventpagerelatedlink',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(related_name='+', blank=True, to='wagtailcore.Page', null=True),
|
||||
field=models.ForeignKey(to='wagtailcore.Page', null=True, related_name='+', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
|
|
@ -358,7 +370,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='eventpagecarouselitem',
|
||||
name='link_page',
|
||||
field=models.ForeignKey(related_name='+', blank=True, to='wagtailcore.Page', null=True),
|
||||
field=models.ForeignKey(to='wagtailcore.Page', null=True, related_name='+', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AddField(
|
||||
|
|
@ -373,14 +385,4 @@ class Migration(migrations.Migration):
|
|||
field=modelcluster.fields.ParentalKey(to='wagtailcore.Page', related_name='advert_placements'),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='groups',
|
||||
field=models.ManyToManyField(related_name='user_set', blank=True, verbose_name='groups', to='auth.Group', related_query_name='user', help_text='The groups this user belongs to. A user will get all permissions granted to each of his/her group.'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='user_permissions',
|
||||
field=models.ManyToManyField(related_name='user_set', blank=True, verbose_name='user permissions', to='auth.Permission', related_query_name='user', help_text='Specific permissions for this user.'),
|
||||
),
|
||||
]
|
||||
0
wagtail/tests/testapp/migrations/__init__.py
Normal file
0
wagtail/tests/testapp/migrations/__init__.py
Normal file
|
|
@ -2,10 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import models
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.conf.urls import url
|
||||
from django.http import HttpResponse
|
||||
|
||||
from taggit.models import TaggedItemBase
|
||||
|
||||
|
|
@ -17,11 +14,10 @@ from wagtail.wagtailcore.fields import RichTextField
|
|||
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel, PageChooserPanel, TabbedInterface, ObjectList
|
||||
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
|
||||
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
|
||||
from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField
|
||||
from wagtail.wagtailsnippets.models import register_snippet
|
||||
from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField
|
||||
from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel
|
||||
from wagtail.wagtailsearch import index
|
||||
from wagtail.contrib.wagtailroutablepage.models import RoutablePage
|
||||
from wagtail.wagtailimages.models import AbstractImage, Image
|
||||
|
||||
|
||||
|
|
@ -39,50 +35,6 @@ COMMON_PANELS = (
|
|||
)
|
||||
|
||||
|
||||
class CustomUserManager(BaseUserManager):
|
||||
def _create_user(self, username, email, password,
|
||||
is_staff, is_superuser, **extra_fields):
|
||||
"""
|
||||
Creates and saves a User with the given username, email and password.
|
||||
"""
|
||||
if not username:
|
||||
raise ValueError('The given username must be set')
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(username=username, email=email,
|
||||
is_staff=is_staff, is_active=True,
|
||||
is_superuser=is_superuser, **extra_fields)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
def create_user(self, username, email=None, password=None, **extra_fields):
|
||||
return self._create_user(username, email, password, False, False,
|
||||
**extra_fields)
|
||||
|
||||
def create_superuser(self, username, email, password, **extra_fields):
|
||||
return self._create_user(username, email, password, True, True,
|
||||
**extra_fields)
|
||||
|
||||
|
||||
class CustomUser(AbstractBaseUser, PermissionsMixin):
|
||||
username = models.CharField(max_length=100, unique=True)
|
||||
email = models.EmailField(max_length=255, blank=True)
|
||||
is_staff = models.BooleanField(default=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
first_name = models.CharField(max_length=50, blank=True)
|
||||
last_name = models.CharField(max_length=50, blank=True)
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
|
||||
objects = CustomUserManager()
|
||||
|
||||
def get_full_name(self):
|
||||
return self.first_name + ' ' + self.last_name
|
||||
|
||||
def get_short_name(self):
|
||||
return self.first_name
|
||||
|
||||
|
||||
# Link fields
|
||||
|
||||
class LinkFields(models.Model):
|
||||
|
|
@ -365,29 +317,6 @@ class Advert(models.Model):
|
|||
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
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
class StandardIndex(Page):
|
||||
""" Index for the site, not allowed to be placed anywhere """
|
||||
parent_page_types = []
|
||||
|
|
@ -432,77 +361,6 @@ class BusinessChild(Page):
|
|||
parent_page_types = ['tests.BusinessIndex', BusinessSubIndex]
|
||||
|
||||
|
||||
class SearchTest(models.Model, index.Indexed):
|
||||
title = models.CharField(max_length=255)
|
||||
content = models.TextField()
|
||||
live = models.BooleanField(default=False)
|
||||
published_date = models.DateField(null=True)
|
||||
|
||||
search_fields = [
|
||||
index.SearchField('title', partial_match=True),
|
||||
index.SearchField('content'),
|
||||
index.SearchField('callable_indexed_field'),
|
||||
index.FilterField('title'),
|
||||
index.FilterField('live'),
|
||||
index.FilterField('published_date'),
|
||||
]
|
||||
|
||||
def callable_indexed_field(self):
|
||||
return "Callable"
|
||||
|
||||
@classmethod
|
||||
def get_indexed_objects(cls):
|
||||
indexed_objects = super(SearchTest, cls).get_indexed_objects()
|
||||
|
||||
# Exclude SearchTests that have a SearchTestChild to stop update_index creating duplicates
|
||||
if cls is SearchTest:
|
||||
indexed_objects = indexed_objects.exclude(
|
||||
id__in=SearchTestChild.objects.all().values_list('searchtest_ptr_id', flat=True)
|
||||
)
|
||||
|
||||
# Exclude SearchTests that have the title "Don't index me!"
|
||||
indexed_objects = indexed_objects.exclude(title="Don't index me!")
|
||||
|
||||
return indexed_objects
|
||||
|
||||
def get_indexed_instance(self):
|
||||
# Check if there is a SearchTestChild that descends from this
|
||||
child = SearchTestChild.objects.filter(searchtest_ptr_id=self.id).first()
|
||||
|
||||
# Return the child if there is one, otherwise return self
|
||||
return child or self
|
||||
|
||||
class SearchTestChild(SearchTest):
|
||||
subtitle = models.CharField(max_length=255, null=True, blank=True)
|
||||
extra_content = models.TextField()
|
||||
|
||||
search_fields = SearchTest.search_fields + [
|
||||
index.SearchField('subtitle', partial_match=True),
|
||||
index.SearchField('extra_content'),
|
||||
]
|
||||
|
||||
|
||||
def routable_page_external_view(request, arg):
|
||||
return HttpResponse("EXTERNAL VIEW: " + arg)
|
||||
|
||||
class RoutablePageTest(RoutablePage):
|
||||
subpage_urls = (
|
||||
url(r'^$', 'main', name='main'),
|
||||
url(r'^archive/year/(\d+)/$', 'archive_by_year', name='archive_by_year'),
|
||||
url(r'^archive/author/(?P<author_slug>.+)/$', 'archive_by_author', name='archive_by_author'),
|
||||
url(r'^external/(.+)/$', routable_page_external_view, name='external_view')
|
||||
)
|
||||
|
||||
def archive_by_year(self, request, year):
|
||||
return HttpResponse("ARCHIVE BY YEAR: " + str(year))
|
||||
|
||||
def archive_by_author(self, request, author_slug):
|
||||
return HttpResponse("ARCHIVE BY AUTHOR: " + author_slug)
|
||||
|
||||
def main(self, request):
|
||||
return HttpResponse("MAIN VIEW")
|
||||
|
||||
|
||||
class TaggedPageTag(TaggedItemBase):
|
||||
content_object = ParentalKey('tests.TaggedPage', related_name='tagged_items')
|
||||
|
||||
|
|
@ -530,17 +388,6 @@ class SnippetChooserModel(models.Model):
|
|||
]
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
class CustomImageWithoutAdminFormFields(AbstractImage):
|
||||
caption = models.CharField(max_length=255)
|
||||
not_editable_field = models.CharField(max_length=255)
|
||||
13
wagtail/tests/testapp/templates/tests/base.html
Normal file
13
wagtail/tests/testapp/templates/tests/base.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{% load wagtailuserbar %}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block html_title %}{{ self.title }}{% endblock %}</title>
|
||||
</head>
|
||||
<body>
|
||||
{% wagtailuserbar %}
|
||||
<h1>{{ self.title }}</h1>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{% extends "tests/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Business Child</h2>
|
||||
{% endblock %}
|
||||
5
wagtail/tests/testapp/templates/tests/event_index.html
Normal file
5
wagtail/tests/testapp/templates/tests/event_index.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{% extends "tests/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% include "tests/includes/event_listing.html" %}
|
||||
{% endblock %}
|
||||
12
wagtail/tests/testapp/templates/tests/event_page.html
Normal file
12
wagtail/tests/testapp/templates/tests/event_page.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{% extends "tests/base.html" %}
|
||||
{% load wagtailcore_tags wagtailimages_tags %}
|
||||
|
||||
{% block html_title %}Event: {{ self.title }}{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Event</h2>
|
||||
{% if self.feed_image %}
|
||||
{% image self.feed_image width-200 class="feed-image" %}
|
||||
{% endif %}
|
||||
{{ self.body|richtext }}
|
||||
<p><a href="{% slugurl 'events' %}">Back to events index</a></p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{% extends "tests/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<p>This event is invitation only. Please enter your password to see the details.</p>
|
||||
<form action="{{ action_url }}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Continue" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
10
wagtail/tests/testapp/templates/tests/form_page.html
Normal file
10
wagtail/tests/testapp/templates/tests/form_page.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{% extends "tests/base.html" %}
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
{% block content %}
|
||||
<form action="{% pageurl self %}" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit">
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{% extends "tests/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<p>Thank you for your feedback.</p>
|
||||
{% endblock %}
|
||||
5
wagtail/tests/testapp/templates/tests/simple_page.html
Normal file
5
wagtail/tests/testapp/templates/tests/simple_page.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{% extends "tests/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Simple page</h2>
|
||||
{% endblock %}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
from django.template.loader import render_to_string
|
||||
from django.core.mail import send_mail
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q
|
||||
|
||||
from wagtail.wagtailcore.models import PageRevision, GroupPagePermission
|
||||
from wagtail.wagtailusers.models import UserProfile
|
||||
|
||||
# The following will check to see if we can import task from celery -
|
||||
# if not then we definitely haven't installed it
|
||||
try:
|
||||
from celery.decorators import task
|
||||
NO_CELERY = False
|
||||
except:
|
||||
NO_CELERY = True
|
||||
|
||||
|
||||
# However, we could have installed celery for other projects. So we will also
|
||||
# check if we have defined the BROKER_URL setting. If not then definitely we
|
||||
# haven't configured it.
|
||||
if NO_CELERY or not hasattr(settings, 'BROKER_URL'):
|
||||
# So if we enter here we will define a different "task" decorator that
|
||||
# just returns the original function and sets its delay attribute to
|
||||
# point to the original function: This way, the send_notification
|
||||
# function will be actually called instead of the the
|
||||
# send_notification.delay()
|
||||
def task(f):
|
||||
f.delay=f
|
||||
return f
|
||||
|
||||
def users_with_page_permission(page, permission_type, include_superusers=True):
|
||||
# Get user model
|
||||
User = get_user_model()
|
||||
|
||||
# Find GroupPagePermission records of the given type that apply to this page or an ancestor
|
||||
ancestors_and_self = list(page.get_ancestors()) + [page]
|
||||
perm = GroupPagePermission.objects.filter(permission_type=permission_type, page__in=ancestors_and_self)
|
||||
q = Q(groups__page_permissions=perm)
|
||||
|
||||
# Include superusers
|
||||
if include_superusers:
|
||||
q |= Q(is_superuser=True)
|
||||
|
||||
return User.objects.filter(is_active=True).filter(q).distinct()
|
||||
|
||||
|
||||
@task
|
||||
def send_notification(page_revision_id, notification, excluded_user_id):
|
||||
# Get revision
|
||||
revision = PageRevision.objects.get(id=page_revision_id)
|
||||
|
||||
# Get list of recipients
|
||||
if notification == 'submitted':
|
||||
# Get list of publishers
|
||||
recipients = users_with_page_permission(revision.page, 'publish')
|
||||
elif notification in ['rejected', 'approved']:
|
||||
# Get submitter
|
||||
recipients = [revision.user]
|
||||
else:
|
||||
return
|
||||
|
||||
# Get list of email addresses
|
||||
email_addresses = [
|
||||
recipient.email for recipient in recipients
|
||||
if recipient.email and recipient.id != excluded_user_id and getattr(UserProfile.get_for_user(recipient), notification + '_notifications')
|
||||
]
|
||||
|
||||
# Return if there are no email addresses
|
||||
if not email_addresses:
|
||||
return
|
||||
|
||||
# Get email subject and content
|
||||
template = 'wagtailadmin/notifications/' + notification + '.html'
|
||||
rendered_template = render_to_string(template, dict(revision=revision, settings=settings)).split('\n')
|
||||
email_subject = rendered_template[0]
|
||||
email_content = '\n'.join(rendered_template[1:])
|
||||
|
||||
# Get from email
|
||||
if hasattr(settings, 'WAGTAILADMIN_NOTIFICATION_FROM_EMAIL'):
|
||||
from_email = settings.WAGTAILADMIN_NOTIFICATION_FROM_EMAIL
|
||||
elif hasattr(settings, 'DEFAULT_FROM_EMAIL'):
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
else:
|
||||
from_email = 'webmaster@localhost'
|
||||
|
||||
# Send email
|
||||
send_mail(email_subject, email_content, from_email, email_addresses)
|
||||
|
||||
|
||||
@task
|
||||
def send_email_task(email_subject, email_content, email_addresses, from_email=None):
|
||||
if not from_email:
|
||||
if hasattr(settings, 'WAGTAILADMIN_NOTIFICATION_FROM_EMAIL'):
|
||||
from_email = settings.WAGTAILADMIN_NOTIFICATION_FROM_EMAIL
|
||||
elif hasattr(settings, 'DEFAULT_FROM_EMAIL'):
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
else:
|
||||
from_email = 'webmaster@localhost'
|
||||
|
||||
send_mail(email_subject, email_content, from_email, email_addresses)
|
||||
|
|
@ -2,5 +2,5 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block item_content %}
|
||||
<a href="{% url 'wagtailadmin_pages_add_subpage' self.parent_page.id %}" target="_parent" class="action icon icon-plus" title="{% trans 'Add another page at this level' %}">{% trans 'Add' %}</a>
|
||||
{% endblock %}
|
||||
<a href="{% url 'wagtailadmin_pages_add_subpage' self.page.id %}" target="_parent" class="action icon icon-plus" title="{% trans 'Add a child page' %}">{% trans 'Add' %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from wagtail.wagtailadmin.widgets import AdminPageChooser, AdminDateInput, Admin
|
|||
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
|
||||
from wagtail.wagtailcore.models import Page, Site
|
||||
from wagtail.wagtailcore.fields import RichTextArea
|
||||
from wagtail.tests.models import PageChooserModel, EventPageChooserModel, EventPage, EventPageSpeaker, SimplePage
|
||||
from wagtail.tests.testapp.models import PageChooserModel, EventPageChooserModel, EventPage, EventPageSpeaker, SimplePage
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.utils.deprecation import RemovedInWagtail12Warning
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.test import TestCase
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.tests.models import SimplePage
|
||||
from wagtail.tests.testapp.models import SimplePage
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from django.core.paginator import Paginator
|
|||
from django.db.models.signals import pre_delete, post_delete
|
||||
from django.utils import timezone
|
||||
|
||||
from wagtail.tests.models import (
|
||||
from wagtail.tests.testapp.models import (
|
||||
SimplePage, EventPage, EventPageCarouselItem,
|
||||
StandardIndex, StandardChild,
|
||||
BusinessIndex, BusinessChild, BusinessSubIndex,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.test import TestCase
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from wagtail.wagtailcore.models import Page, PageViewRestriction
|
||||
from wagtail.tests.models import SimplePage
|
||||
from wagtail.tests.testapp.models import SimplePage
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from django.contrib.auth.models import AnonymousUser
|
|||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.tests.testapp.models import BusinessIndex, BusinessChild
|
||||
|
||||
|
||||
class TestUserbarTag(TestCase):
|
||||
|
|
@ -60,6 +61,37 @@ class TestUserbarFrontend(TestCase, WagtailTestUtils):
|
|||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
|
||||
class TestUserbarAddLink(TestCase, WagtailTestUtils):
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
self.homepage = Page.objects.get(url_path='/home/')
|
||||
self.event_index = Page.objects.get(url_path='/home/events/')
|
||||
|
||||
self.business_index = BusinessIndex(title='Business', slug='business', live=True)
|
||||
self.homepage.add_child(instance=self.business_index)
|
||||
|
||||
self.business_child = BusinessChild(title='Business Child', slug='child', live=True)
|
||||
self.business_index.add_child(instance=self.business_child)
|
||||
|
||||
def test_page_allowing_subpages(self):
|
||||
response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.event_index.id, )))
|
||||
|
||||
# page allows subpages, so the 'add page' button should show
|
||||
expected_url = reverse('wagtailadmin_pages_add_subpage', args=(self.event_index.id, ))
|
||||
expected_link = '<a href="%s" target="_parent" class="action icon icon-plus" title="Add a child page">Add</a>' % expected_url
|
||||
self.assertContains(response, expected_link)
|
||||
|
||||
def test_page_disallowing_subpages(self):
|
||||
response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.business_child.id, )))
|
||||
|
||||
# page disallows subpages, so the 'add page' button shouldn't show
|
||||
expected_url = reverse('wagtailadmin_pages_add_subpage', args=(self.business_index.id, ))
|
||||
expected_link = '<a href="%s" target="_parent" class="action icon icon-plus" title="Add a child page">Add</a>' % expected_url
|
||||
self.assertNotContains(response, expected_link)
|
||||
|
||||
|
||||
class TestUserbarModeration(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from django.test import TestCase
|
||||
from django.test import TestCase, override_settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core import mail
|
||||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailadmin.tasks import send_email_task
|
||||
from wagtail.wagtailadmin.utils import send_mail
|
||||
|
||||
|
||||
class TestHome(TestCase, WagtailTestUtils):
|
||||
|
|
@ -56,15 +56,48 @@ class TestEditorHooks(TestCase, WagtailTestUtils):
|
|||
self.assertContains(response, '<script src="/path/to/my/custom.js"></script>')
|
||||
|
||||
|
||||
class TestSendEmailTask(TestCase):
|
||||
class TestSendMail(TestCase):
|
||||
def test_send_email(self):
|
||||
send_email_task("Test subject", "Test content", ["nobody@email.com"], "test@email.com")
|
||||
send_mail("Test subject", "Test content", ["nobody@email.com"], "test@email.com")
|
||||
|
||||
# Check that the email was sent
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject, "Test subject")
|
||||
self.assertEqual(mail.outbox[0].body, "Test content")
|
||||
self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
|
||||
self.assertEqual(mail.outbox[0].from_email, "test@email.com")
|
||||
|
||||
@override_settings(WAGTAILADMIN_NOTIFICATION_FROM_EMAIL='anothertest@email.com')
|
||||
def test_send_fallback_to_wagtailadmin_notification_from_email_setting(self):
|
||||
send_mail("Test subject", "Test content", ["nobody@email.com"])
|
||||
|
||||
# Check that the email was sent
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject, "Test subject")
|
||||
self.assertEqual(mail.outbox[0].body, "Test content")
|
||||
self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
|
||||
self.assertEqual(mail.outbox[0].from_email, "anothertest@email.com")
|
||||
|
||||
@override_settings(DEFAULT_FROM_EMAIL='yetanothertest@email.com')
|
||||
def test_send_fallback_to_default_from_email_setting(self):
|
||||
send_mail("Test subject", "Test content", ["nobody@email.com"])
|
||||
|
||||
# Check that the email was sent
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject, "Test subject")
|
||||
self.assertEqual(mail.outbox[0].body, "Test content")
|
||||
self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
|
||||
self.assertEqual(mail.outbox[0].from_email, "yetanothertest@email.com")
|
||||
|
||||
def test_send_default_from_email(self):
|
||||
send_mail("Test subject", "Test content", ["nobody@email.com"])
|
||||
|
||||
# Check that the email was sent
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject, "Test subject")
|
||||
self.assertEqual(mail.outbox[0].body, "Test content")
|
||||
self.assertEqual(mail.outbox[0].to, ["nobody@email.com"])
|
||||
self.assertEqual(mail.outbox[0].from_email, "webmaster@localhost")
|
||||
|
||||
|
||||
class TestExplorerNavView(TestCase, WagtailTestUtils):
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class AddPageItem(BaseItem):
|
|||
if not request.user.has_perm('wagtailadmin.access_admin'):
|
||||
return ""
|
||||
|
||||
# Don't render if user doesn't have ability to add siblings
|
||||
permission_checker = self.page.get_parent().permissions_for_user(request.user)
|
||||
# Don't render if user doesn't have ability to add children here
|
||||
permission_checker = self.page.permissions_for_user(request.user)
|
||||
if not permission_checker.can_add_subpage():
|
||||
return ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
from django.template.loader import render_to_string
|
||||
from django.core.mail import send_mail as django_send_mail
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q
|
||||
|
||||
from modelcluster.fields import ParentalKey
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailcore.models import Page, PageRevision, GroupPagePermission
|
||||
from wagtail.wagtailusers.models import UserProfile
|
||||
|
||||
|
||||
def get_object_usage(obj):
|
||||
|
|
@ -34,3 +41,65 @@ def get_object_usage(obj):
|
|||
)
|
||||
|
||||
return pages
|
||||
|
||||
|
||||
def users_with_page_permission(page, permission_type, include_superusers=True):
|
||||
# Get user model
|
||||
User = get_user_model()
|
||||
|
||||
# Find GroupPagePermission records of the given type that apply to this page or an ancestor
|
||||
ancestors_and_self = list(page.get_ancestors()) + [page]
|
||||
perm = GroupPagePermission.objects.filter(permission_type=permission_type, page__in=ancestors_and_self)
|
||||
q = Q(groups__page_permissions=perm)
|
||||
|
||||
# Include superusers
|
||||
if include_superusers:
|
||||
q |= Q(is_superuser=True)
|
||||
|
||||
return User.objects.filter(is_active=True).filter(q).distinct()
|
||||
|
||||
|
||||
def send_mail(email_subject, email_content, email_addresses, from_email=None):
|
||||
if not from_email:
|
||||
if hasattr(settings, 'WAGTAILADMIN_NOTIFICATION_FROM_EMAIL'):
|
||||
from_email = settings.WAGTAILADMIN_NOTIFICATION_FROM_EMAIL
|
||||
elif hasattr(settings, 'DEFAULT_FROM_EMAIL'):
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
else:
|
||||
from_email = 'webmaster@localhost'
|
||||
|
||||
django_send_mail(email_subject, email_content, from_email, email_addresses)
|
||||
|
||||
|
||||
def send_notification(page_revision_id, notification, excluded_user_id):
|
||||
# Get revision
|
||||
revision = PageRevision.objects.get(id=page_revision_id)
|
||||
|
||||
# Get list of recipients
|
||||
if notification == 'submitted':
|
||||
# Get list of publishers
|
||||
recipients = users_with_page_permission(revision.page, 'publish')
|
||||
elif notification in ['rejected', 'approved']:
|
||||
# Get submitter
|
||||
recipients = [revision.user]
|
||||
else:
|
||||
return
|
||||
|
||||
# Get list of email addresses
|
||||
email_addresses = [
|
||||
recipient.email for recipient in recipients
|
||||
if recipient.email and recipient.id != excluded_user_id and getattr(UserProfile.get_for_user(recipient), notification + '_notifications')
|
||||
]
|
||||
|
||||
# Return if there are no email addresses
|
||||
if not email_addresses:
|
||||
return
|
||||
|
||||
# Get email subject and content
|
||||
template = 'wagtailadmin/notifications/' + notification + '.html'
|
||||
rendered_template = render_to_string(template, dict(revision=revision, settings=settings)).split('\n')
|
||||
email_subject = rendered_template[0]
|
||||
email_content = '\n'.join(rendered_template[1:])
|
||||
|
||||
# Send email
|
||||
send_mail(email_subject, email_content, email_addresses)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ from django.db.models import Count
|
|||
|
||||
from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList
|
||||
from wagtail.wagtailadmin.forms import SearchForm, CopyForm
|
||||
from wagtail.wagtailadmin import tasks, signals
|
||||
from wagtail.wagtailadmin.utils import send_notification
|
||||
from wagtail.wagtailadmin import signals
|
||||
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.wagtailcore.models import Page, PageRevision, get_navigation_menu_items
|
||||
|
|
@ -225,7 +226,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
|
|||
messages.success(request, _("Page '{0}' published.").format(page.title))
|
||||
elif is_submitting:
|
||||
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title))
|
||||
tasks.send_notification.delay(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
send_notification(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
else:
|
||||
messages.success(request, _("Page '{0}' created.").format(page.title))
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ def edit(request, page_id):
|
|||
messages.button(reverse('wagtailadmin_pages_view_draft', args=(page_id,)), _('View draft')),
|
||||
messages.button(reverse('wagtailadmin_pages_edit', args=(page_id,)), _('Edit'))
|
||||
])
|
||||
tasks.send_notification.delay(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
send_notification(page.get_latest_revision().id, 'submitted', request.user.id)
|
||||
else:
|
||||
messages.success(request, _("Page '{0}' updated.").format(page.title))
|
||||
|
||||
|
|
@ -782,7 +783,7 @@ def approve_moderation(request, revision_id):
|
|||
if request.method == 'POST':
|
||||
revision.approve_moderation()
|
||||
messages.success(request, _("Page '{0}' published.").format(revision.page.title))
|
||||
tasks.send_notification.delay(revision.id, 'approved', request.user.id)
|
||||
send_notification(revision.id, 'approved', request.user.id)
|
||||
|
||||
return redirect('wagtailadmin_home')
|
||||
|
||||
|
|
@ -799,7 +800,7 @@ def reject_moderation(request, revision_id):
|
|||
if request.method == 'POST':
|
||||
revision.reject_moderation()
|
||||
messages.success(request, _("Page '{0}' rejected for publication.").format(revision.page.title))
|
||||
tasks.send_notification.delay(revision.id, 'rejected', request.user.id)
|
||||
send_notification(revision.id, 'rejected', request.user.id)
|
||||
|
||||
return redirect('wagtailadmin_home')
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from django.db import models
|
|||
|
||||
from wagtail.wagtailcore.models import Page, PageRevision
|
||||
from wagtail.wagtailcore.signals import page_published, page_unpublished
|
||||
from wagtail.tests.models import SimplePage, EventPage
|
||||
from wagtail.tests.testapp.models import SimplePage, EventPage
|
||||
|
||||
|
||||
class TestFixTreeCommand(TestCase):
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from django.contrib.contenttypes.models import ContentType
|
|||
from django.contrib.auth import get_user_model
|
||||
|
||||
from wagtail.wagtailcore.models import Page, Site
|
||||
from wagtail.tests.models import EventPage, EventIndex, SimplePage, PageWithOldStyleRouteMethod, BusinessIndex, BusinessSubIndex, BusinessChild, StandardIndex
|
||||
from wagtail.tests.testapp.models import EventPage, EventIndex, SimplePage, PageWithOldStyleRouteMethod, BusinessIndex, BusinessSubIndex, BusinessChild, StandardIndex
|
||||
|
||||
|
||||
class TestSiteRouting(TestCase):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.test import TestCase
|
|||
from django.contrib.auth import get_user_model
|
||||
|
||||
from wagtail.wagtailcore.models import Page, UserPagePermissionsProxy
|
||||
from wagtail.tests.models import EventPage
|
||||
from wagtail.tests.testapp.models import EventPage
|
||||
|
||||
|
||||
class TestPagePermission(TestCase):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.test import TestCase
|
||||
|
||||
from wagtail.wagtailcore.models import Page, PageViewRestriction
|
||||
from wagtail.tests.models import EventPage
|
||||
from wagtail.tests.testapp.models import EventPage
|
||||
|
||||
|
||||
class TestPageQuerySet(TestCase):
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from bs4 import BeautifulSoup
|
|||
|
||||
|
||||
class TestPageLinkHandler(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def test_get_db_attributes(self):
|
||||
soup = BeautifulSoup(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from django.utils.safestring import SafeString
|
|||
from wagtail.wagtailcore.models import Page, Site
|
||||
from wagtail.wagtailcore.templatetags.wagtailcore_tags import richtext
|
||||
from wagtail.wagtailcore.utils import resolve_model_string
|
||||
from wagtail.tests.models import SimplePage
|
||||
from wagtail.tests.testapp.models import SimplePage
|
||||
|
||||
|
||||
class TestPageUrlTags(TestCase):
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from django.test.utils import override_settings
|
|||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
||||
from wagtail.tests.models import EventPage, EventPageRelatedLink
|
||||
from wagtail.tests.testapp.models import EventPage, EventPageRelatedLink
|
||||
from wagtail.wagtaildocs.models import Document
|
||||
|
||||
from wagtail.wagtaildocs import models
|
||||
|
|
@ -340,7 +340,7 @@ class TestDocumentFilenameProperties(TestCase):
|
|||
|
||||
|
||||
class TestUsageCount(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
|
@ -391,7 +391,7 @@ class TestUsageCount(TestCase, WagtailTestUtils):
|
|||
|
||||
|
||||
class TestGetUsage(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
|
@ -581,7 +581,7 @@ class TestServeView(TestCase):
|
|||
|
||||
|
||||
class TestDocumentRichTextLinkHandler(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def test_get_db_attributes(self):
|
||||
soup = BeautifulSoup(
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ OEMBED_ENDPOINTS = {
|
|||
],
|
||||
"http://api.instagram.com/oembed": [
|
||||
"^http://instagr\\.am/p/.+$",
|
||||
"^http://instagram\\.com/p/.+$"
|
||||
"^http[s]?://instagram\\.com/p/.+$"
|
||||
],
|
||||
"https://www.slideshare.net/api/oembed/2": [
|
||||
"^http://www\\.slideshare\\.net/.+$"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from django.core.serializers.json import DjangoJSONEncoder
|
|||
|
||||
from wagtail.wagtailcore.models import Page, Orderable, UserPagePermissionsProxy, get_page_types
|
||||
from wagtail.wagtailadmin.edit_handlers import FieldPanel
|
||||
from wagtail.wagtailadmin import tasks
|
||||
from wagtail.wagtailadmin.utils import send_mail
|
||||
|
||||
from .forms import FormBuilder
|
||||
|
||||
|
|
@ -194,7 +194,7 @@ class AbstractEmailForm(AbstractForm):
|
|||
|
||||
if self.to_address:
|
||||
content = '\n'.join([x[1].label + ': ' + form.data.get(x[0]) for x in form.fields.items()])
|
||||
tasks.send_email_task.delay(self.subject, content, [self.to_address], self.from_address,)
|
||||
send_mail(self.subject, content, [self.to_address], self.from_address,)
|
||||
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from django.core.urlresolvers import reverse
|
|||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailforms.models import FormSubmission
|
||||
from wagtail.wagtailforms.forms import FormBuilder
|
||||
from wagtail.tests.models import FormPage, FormField
|
||||
from wagtail.tests.testapp.models import FormPage, FormField
|
||||
|
||||
|
||||
class TestFormSubmission(TestCase):
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ def image_delete(sender, instance, **kwargs):
|
|||
|
||||
def get_image_model():
|
||||
from django.conf import settings
|
||||
from django.db.models import get_model
|
||||
from django.apps import apps
|
||||
|
||||
try:
|
||||
app_label, model_name = settings.WAGTAILIMAGES_IMAGE_MODEL.split('.')
|
||||
|
|
@ -270,7 +270,7 @@ def get_image_model():
|
|||
except ValueError:
|
||||
raise ImproperlyConfigured("WAGTAILIMAGES_IMAGE_MODEL must be of the form 'app_label.model_name'")
|
||||
|
||||
image_model = get_model(app_label, model_name)
|
||||
image_model = apps.get_model(app_label, model_name)
|
||||
if image_model is None:
|
||||
raise ImproperlyConfigured("WAGTAILIMAGES_IMAGE_MODEL refers to model '%s' that has not been installed" % settings.WAGTAILIMAGES_IMAGE_MODEL)
|
||||
return image_model
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from django.db import connection
|
|||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.tests.models import EventPage, EventPageCarouselItem
|
||||
from wagtail.tests.testapp.models import EventPage, EventPageCarouselItem
|
||||
from wagtail.wagtailimages.models import Rendition, Filter, SourceImageIOError
|
||||
from wagtail.wagtailimages.rect import Rect
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ class TestRenditions(TestCase):
|
|||
|
||||
|
||||
class TestUsageCount(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.image = Image.objects.create(
|
||||
|
|
@ -184,7 +184,7 @@ class TestUsageCount(TestCase):
|
|||
|
||||
|
||||
class TestGetUsage(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.image = Image.objects.create(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ from wagtail.wagtailimages.rich_text import ImageEmbedHandler
|
|||
|
||||
|
||||
class TestImageEmbedHandler(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
|
||||
def test_get_db_attributes(self):
|
||||
soup = BeautifulSoup(
|
||||
'<b data-id="test-id" data-format="test-format" data-alt="test-alt">foo</b>'
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from django.db import models
|
|||
from taggit.forms import TagField, TagWidget
|
||||
|
||||
from wagtail.utils.deprecation import RemovedInWagtail12Warning
|
||||
from wagtail.tests.models import CustomImageWithAdminFormFields, CustomImageWithoutAdminFormFields
|
||||
from wagtail.tests.testapp.models import CustomImageWithAdminFormFields, CustomImageWithoutAdminFormFields
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.wagtailimages.utils import generate_signature, verify_signature
|
||||
from wagtail.wagtailimages.rect import Rect
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import warnings
|
|||
from six import string_types
|
||||
|
||||
from django.db import models
|
||||
from django.apps import apps
|
||||
|
||||
|
||||
class Indexed(object):
|
||||
|
|
@ -74,7 +75,7 @@ class Indexed(object):
|
|||
|
||||
def get_indexed_models():
|
||||
return [
|
||||
model for model in models.get_models()
|
||||
model for model in apps.get_models()
|
||||
if issubclass(model, Indexed) and not model._meta.abstract
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from django.conf import settings
|
|||
from django.core import management
|
||||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.tests import models
|
||||
from wagtail.tests.search import models
|
||||
from wagtail.wagtailsearch.backends import get_search_backend, InvalidSearchBackendError
|
||||
from wagtail.wagtailsearch.backends.db import DBSearch
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import json
|
|||
from django.test import TestCase
|
||||
from django.db.models import Q
|
||||
|
||||
from wagtail.tests import models
|
||||
from wagtail.tests.search import models
|
||||
from .test_backends import BackendTests
|
||||
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_none_query_string(self):
|
||||
|
|
@ -194,7 +194,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), None)
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'match_all': {}}}}
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match_all': {}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_filter(self):
|
||||
|
|
@ -202,7 +202,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title="Test"), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_and_filter(self):
|
||||
|
|
@ -210,7 +210,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title="Test", live=True), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
|
||||
# Make sure field filters are sorted (as they can be in any order which may cause false positives)
|
||||
query = query.to_es()
|
||||
|
|
@ -229,7 +229,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
field_filters[:] = sorted(field_filters, key=lambda f: list(f['term'].keys())[0])
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query, expected_result)
|
||||
|
||||
def test_negated_filter(self):
|
||||
|
|
@ -237,7 +237,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.exclude(live=True), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_fields(self):
|
||||
|
|
@ -245,7 +245,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title'])
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}}
|
||||
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_exact_lookup(self):
|
||||
|
|
@ -253,7 +253,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__exact="Test"), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_none_lookup(self):
|
||||
|
|
@ -261,7 +261,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title=None), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_isnull_true_lookup(self):
|
||||
|
|
@ -269,7 +269,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=True), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_isnull_false_lookup(self):
|
||||
|
|
@ -277,7 +277,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=False), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_startswith_lookup(self):
|
||||
|
|
@ -285,7 +285,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__startswith="Test"), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_gt_lookup(self):
|
||||
|
|
@ -295,7 +295,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_lt_lookup(self):
|
||||
|
|
@ -303,7 +303,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_gte_lookup(self):
|
||||
|
|
@ -311,7 +311,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_lte_lookup(self):
|
||||
|
|
@ -319,7 +319,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
def test_range_lookup(self):
|
||||
|
|
@ -330,7 +330,7 @@ class TestElasticSearchQuery(TestCase):
|
|||
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query.to_es(), expected_result)
|
||||
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ class TestElasticSearchMapping(TestCase):
|
|||
self.obj.save()
|
||||
|
||||
def test_get_document_type(self):
|
||||
self.assertEqual(self.es_mapping.get_document_type(), 'tests_searchtest')
|
||||
self.assertEqual(self.es_mapping.get_document_type(), 'searchtests_searchtest')
|
||||
|
||||
def test_get_mapping(self):
|
||||
# Build mapping
|
||||
|
|
@ -366,7 +366,7 @@ class TestElasticSearchMapping(TestCase):
|
|||
|
||||
# Check
|
||||
expected_result = {
|
||||
'tests_searchtest': {
|
||||
'searchtests_searchtest': {
|
||||
'properties': {
|
||||
'pk': {'index': 'not_analyzed', 'type': 'string', 'store': 'yes', 'include_in_all': False},
|
||||
'content_type': {'index': 'not_analyzed', 'type': 'string', 'include_in_all': False},
|
||||
|
|
@ -384,7 +384,7 @@ class TestElasticSearchMapping(TestCase):
|
|||
self.assertDictEqual(mapping, expected_result)
|
||||
|
||||
def test_get_document_id(self):
|
||||
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'tests_searchtest:' + str(self.obj.pk))
|
||||
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'searchtests_searchtest:' + str(self.obj.pk))
|
||||
|
||||
def test_get_document(self):
|
||||
# Get document
|
||||
|
|
@ -393,7 +393,7 @@ class TestElasticSearchMapping(TestCase):
|
|||
# Check
|
||||
expected_result = {
|
||||
'pk': str(self.obj.pk),
|
||||
'content_type': 'tests_searchtest',
|
||||
'content_type': 'searchtests_searchtest',
|
||||
'_partials': ['Hello'],
|
||||
'live_filter': False,
|
||||
'published_date_filter': None,
|
||||
|
|
@ -430,7 +430,7 @@ class TestElasticSearchMappingInheritance(TestCase):
|
|||
self.obj.save()
|
||||
|
||||
def test_get_document_type(self):
|
||||
self.assertEqual(self.es_mapping.get_document_type(), 'tests_searchtest_tests_searchtestchild')
|
||||
self.assertEqual(self.es_mapping.get_document_type(), 'searchtests_searchtest_searchtests_searchtestchild')
|
||||
|
||||
def test_get_mapping(self):
|
||||
# Build mapping
|
||||
|
|
@ -438,7 +438,7 @@ class TestElasticSearchMappingInheritance(TestCase):
|
|||
|
||||
# Check
|
||||
expected_result = {
|
||||
'tests_searchtest_tests_searchtestchild': {
|
||||
'searchtests_searchtest_searchtests_searchtestchild': {
|
||||
'properties': {
|
||||
# New
|
||||
'extra_content': {'type': 'string', 'include_in_all': True},
|
||||
|
|
@ -464,7 +464,7 @@ class TestElasticSearchMappingInheritance(TestCase):
|
|||
# This must be tests_searchtest instead of 'tests_searchtest_tests_searchtestchild'
|
||||
# as it uses the contents base content type name.
|
||||
# This prevents the same object being accidentally indexed twice.
|
||||
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'tests_searchtest:' + str(self.obj.pk))
|
||||
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'searchtests_searchtest:' + str(self.obj.pk))
|
||||
|
||||
def test_get_document(self):
|
||||
# Build document
|
||||
|
|
@ -481,7 +481,7 @@ class TestElasticSearchMappingInheritance(TestCase):
|
|||
'subtitle': 'World',
|
||||
|
||||
# Changed
|
||||
'content_type': 'tests_searchtest_tests_searchtestchild',
|
||||
'content_type': 'searchtests_searchtest_searchtests_searchtestchild',
|
||||
|
||||
# Inherited
|
||||
'pk': str(self.obj.pk),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from django.core import paginator
|
|||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
|
||||
from wagtail.tests.models import EventPage
|
||||
from wagtail.tests.testapp.models import EventPage
|
||||
|
||||
|
||||
class TestSearchView(TestCase):
|
||||
|
|
|
|||
|
|
@ -3,18 +3,18 @@ import warnings
|
|||
from django.test import TestCase
|
||||
|
||||
from wagtail.wagtailsearch import index
|
||||
from wagtail.tests import models
|
||||
from wagtail.tests.search import models
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
|
||||
|
||||
class TestContentTypeNames(TestCase):
|
||||
def test_base_content_type_name(self):
|
||||
name = models.SearchTestChild.indexed_get_toplevel_content_type()
|
||||
self.assertEqual(name, 'tests_searchtest')
|
||||
self.assertEqual(name, 'searchtests_searchtest')
|
||||
|
||||
def test_qualified_content_type_name(self):
|
||||
name = models.SearchTestChild.indexed_get_content_type()
|
||||
self.assertEqual(name, 'tests_searchtest_tests_searchtestchild')
|
||||
self.assertEqual(name, 'searchtests_searchtest_searchtests_searchtestchild')
|
||||
|
||||
|
||||
class TestSearchFields(TestCase):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.test import TestCase
|
||||
|
||||
from wagtail.wagtailsearch import signal_handlers
|
||||
from wagtail.tests import models
|
||||
from wagtail.tests.search import models
|
||||
|
||||
|
||||
class TestGetIndexedInstance(TestCase):
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ from django.http import Http404
|
|||
from django.test import TestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from django.test.utils import override_settings
|
||||
from wagtail.tests.models import Advert, AlphaSnippet, ZuluSnippet, SnippetChooserModel, RegisterDecorator, RegisterFunction
|
||||
from wagtail.tests.testapp.models import Advert, SnippetChooserModel
|
||||
from wagtail.tests.snippets.models import AlphaSnippet, ZuluSnippet, RegisterDecorator, RegisterFunction
|
||||
from wagtail.wagtailsnippets.models import register_snippet, SNIPPET_MODELS
|
||||
|
||||
from wagtail.wagtailsnippets.views.snippets import (
|
||||
|
|
@ -91,7 +92,7 @@ class TestSnippetCreateView(TestCase, WagtailTestUtils):
|
|||
|
||||
|
||||
class TestSnippetEditView(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.test_snippet = Advert.objects.get(id=1)
|
||||
|
|
@ -138,7 +139,7 @@ class TestSnippetEditView(TestCase, WagtailTestUtils):
|
|||
|
||||
|
||||
class TestSnippetDelete(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.test_snippet = Advert.objects.get(id=1)
|
||||
|
|
@ -160,7 +161,7 @@ class TestSnippetDelete(TestCase, WagtailTestUtils):
|
|||
|
||||
|
||||
class TestSnippetChooserPanel(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
model = SnippetChooserModel
|
||||
|
|
@ -213,7 +214,7 @@ class TestSnippetOrdering(TestCase):
|
|||
|
||||
|
||||
class TestUsageCount(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
@override_settings(WAGTAIL_USAGE_COUNT_ENABLED=True)
|
||||
def test_snippet_usage_count(self):
|
||||
|
|
@ -222,7 +223,7 @@ class TestUsageCount(TestCase):
|
|||
|
||||
|
||||
class TestUsedBy(TestCase):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
@override_settings(WAGTAIL_USAGE_COUNT_ENABLED=True)
|
||||
def test_snippet_used_by(self):
|
||||
|
|
@ -231,7 +232,7 @@ class TestUsedBy(TestCase):
|
|||
|
||||
|
||||
class TestSnippetChoose(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
|
@ -255,7 +256,7 @@ class TestSnippetChoose(TestCase, WagtailTestUtils):
|
|||
|
||||
|
||||
class TestSnippetChosen(TestCase, WagtailTestUtils):
|
||||
fixtures = ['wagtail/tests/fixtures/test.json']
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.login()
|
||||
|
|
|
|||
Loading…
Reference in a new issue