Пример #1
0
    def test_get_model(self):
        overriding, overridable = apps.get_app_configs()
        Article = apps.get_model('overridable', 'Article')
        self.assertEqual(Article, overridable.get_model('Article'))
        with self.assertRaises(LookupError):
            overriding.get_model('Article')

        article_field_names = {
            field.name
            for field in Article._meta.get_fields()
        }
        self.assertIn('extract', article_field_names)
        self.assertEqual(article_field_names, {
            'id',
            'title',
            'extract',
            'content',
            'author',
        })
        Author = apps.get_model('overridable', 'Author')
        self.assertEqual(Author, overridable.get_model('Author'))
        with self.assertRaises(LookupError):
            overriding.get_model('Author')

        author_field_names = {
            field.name
            for field in Author._meta.get_fields()
        }
        self.assertEqual(author_field_names, {'id', 'name', 'articles'})
Пример #2
0
def get_model(info):
    if isinstance(info, Model):
        return info

    if isinstance(info, six.string_types):
        model = apps.get_model(info)
    elif isinstance(info, (tuple, list)):
        model = apps.get_model(*info)
    elif isinstance(info, dict):
        model = apps.get_model(**info)
    else:
        raise UnexpectedTypeError((str, list, dict), info)

    return model
Пример #3
0
    def handle(self, *labels, **options):
        if not labels:
            models = apps.get_models()
        else:
            models = []
            for label in labels:
                if '.' in label:
                    models.append(apps.get_model(label))
                else:
                    models.extend(apps.get_app_config(label).get_models())

        nested_models = [
            model for model in models if issubclass(model, Nestable)
        ]
        if nested_models:
            for model in nested_models:
                self.stdout.write('Regenerating {0}.{1} ...'.format(
                    model._meta.app_label,
                    model.__name__,
                ))
                with transaction.atomic():
                    model._tree_manager.rebuild()

            self.stdout.write('Trees were successfully regenerated.')
        else:
            self.stdout.write('No tree was found.')
Пример #4
0
    def _clean_options(cls, opts):
        if 'model' not in opts:
            raise AttributeError('You must give a model.')

        model = opts.pop('model')
        if isinstance(model, six.string_types):
            model = apps.get_model(model)

        migration_kwargs = {
            'model': model,
            'fields': opts.pop('fields', None),
            'exclude': opts.pop('exclude', None),
            'use_natural_primary_keys': opts.pop('use_natural_primary_keys',
                                                 False),
            'use_natural_foreign_keys': opts.pop('use_natural_foreign_keys',
                                                 False),
            'use_base_manager': opts.pop('use_base_manager', False),
        }
        serializer = opts.pop('serializer', None)

        if isinstance(serializer, six.string_types):
            serializer = serializers.get_serializer(serializer)

        if isinstance(serializer, collections.Callable):
            serializer = serializer()

        export_kwargs = {
            'serializer': serializer,
        }
        return migration_kwargs, export_kwargs
Пример #5
0
    def get_translation(self, tag):
        """
        Returns the translation object for given language ``tag``.
        """
        tag = self.clean_language_tag(tag)
        if tag not in self._translations:
            Translation = apps.get_model(self._meta.app_label,
                                         self._meta.translation)
            try:
                qs = Translation._default_manager.select_related()
                translation = qs.get(model=self, language__tag=tag)
            except ObjectDoesNotExist:

                if not settings.MULTILINGUAL_FAIL_SILENTLY:
                    raise TranslationDoesNotExist(self, tag)

                if (settings.MULTILINGUAL_FALL_BACK_TO_DEFAULT
                        and settings.MULTILINGUAL_DEFAULT
                        and tag != settings.MULTILINGUAL_DEFAULT):
                    return self.get_translation(settings.MULTILINGUAL_DEFAULT)
                else:
                    translation = None

            self._translations[tag] = translation

        return self._translations[tag]
Пример #6
0
    def _setup(self):
        model = self._model
        if isinstance(model, six.string_types):
            model = apps.get_model(*model.rsplit('.', 1))

        if self._manager is None:
            manager = model._default_manager
        else:
            manager = getattr(model, self._manager)

        self._wrapped = manager.get(**self._lookup_parameters)
Пример #7
0
    def get_all_translations(self):
        Translation = apps.get_model(self._meta.app_label,
                                     self._meta.translation)

        other_translations = Translation._default_manager.filter(
            model=self).exclude(
                language__tag__in=self._translations.keys()).select_related()

        for translation in other_translations:
            self._translations[translation.language.tag] = translation

        tags = list(six.iterkeys(self._translations))
        tags.sort()
        return [self._translations[tag] for tag in tags]
Пример #8
0
    def _clean_options(cls, opts):
        selected_models = opts.pop('models', None)
        model_list = []
        if selected_models:
            for model in selected_models:
                if not isinstance(model, six.string_types):
                    model_list.append(model)
                elif '.' in model:
                    model = apps.get_model(model)
                    model_list.append(model)
                else:
                    app_config = apps.get_app_config(model)
                    model_list.extend(
                        app_config.get_models(include_auto_created=True))

        use_natural_keys = opts.pop('use_natural_keys', False)

        migration_kwargs = {
            'models':
            model_list,
            'use_natural_primary_keys':
            use_natural_keys,
            'use_natural_foreign_keys':
            use_natural_keys,
            'ignore_missing_foreign_keys':
            opts.pop('ignore_missing_foreign_keys', False),
        }
        serializer = opts.pop('serializer', None)
        plan = opts.pop('plan', None)
        batch_size = opts.pop('batch_size', 100)

        if isinstance(serializer, six.string_types):
            serializer = serializers.get_serializer(serializer)

        if isinstance(serializer, collections.Callable):
            serializer = serializer(**opts)

        if isinstance(plan, six.string_types):
            plan = importation_plans.get_plan(plan)

        import_kwargs = {
            'serializer': serializer,
            'plan': plan,
            'batch_size': batch_size,
        }
        return migration_kwargs, import_kwargs
Пример #9
0
    def _clean_options(cls, opts):
        if 'model' not in opts:
            raise AttributeError('You must give a model.')

        model = opts.pop('model')
        if isinstance(model, six.string_types):
            model = apps.get_model(model)

        migration_kwargs = {
            'model':
            model,
            'fields':
            opts.pop('fields', None),
            'exclude':
            opts.pop('exclude', None),
            'use_natural_primary_keys':
            opts.pop('use_natural_primary_keys', False),
            'use_natural_foreign_keys':
            opts.pop('use_natural_foreign_keys', False),
            'ignore_missing_foreign_keys':
            opts.pop('ignore_missing_foreign_keys', False),
        }
        serializer = opts.pop('serializer', None)
        plan = opts.pop('plan', None)
        batch_size = opts.pop('batch_size', 100)

        if isinstance(serializer, six.string_types):
            serializer = serializers.get_serializer(serializer)

        if isinstance(serializer, collections.Callable):
            serializer = serializer(**opts)

        if isinstance(plan, six.string_types):
            plan = importation_plans.get_plan(plan)

        import_kwargs = {
            'serializer': serializer,
            'plan': plan,
            'batch_size': batch_size,
        }
        return migration_kwargs, import_kwargs
Пример #10
0
    def _clean_options(cls, opts):
        selected_models = opts.pop('models', None)
        if not selected_models:
            model_list = apps.get_models(include_auto_created=True)
        else:
            model_list = []
            for model in selected_models:
                if not isinstance(model, six.string_types):
                    model_list.append(model)
                elif '.' in model:
                    model = apps.get_model(model)
                    model_list.append(model)
                else:
                    app_config = apps.get_app_config(model)
                    model_list.extend(
                        app_config.get_models(include_auto_created=True))

        use_natural_keys = opts.pop('use_natural_keys', False)

        migration_kwargs = {
            'models': model_list,
            'use_natural_primary_keys': use_natural_keys,
            'use_natural_foreign_keys': use_natural_keys,
            'use_base_manager': opts.pop('use_base_manager', False),
        }
        serializer = opts.pop('serializer', None)

        if isinstance(serializer, six.string_types):
            serializer = serializers.get_serializer(serializer)

        if isinstance(serializer, collections.Callable):
            serializer = serializer(**opts)

        export_kwargs = {
            'serializer': serializer,
        }
        return migration_kwargs, export_kwargs
Пример #11
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.db.models import Count
from django.utils.html import escape, format_html
from django.utils.translation import ugettext, ugettext_lazy as _

from yepes import admin
from yepes.apps import apps
from yepes.contrib.thumbnails.proxies import ConfigurationProxy

Attachment = apps.get_model('attachments', 'Attachment')
AttachmentCategory = apps.get_model('attachments', 'AttachmentCategory')


class AttachmentAdmin(admin.ModelAdmin):

    autocomplete_lookup_fields = {
        'fk': ['category'],
        'm2m': [],
    }
    fieldsets = [
        (None, {
            'fields': [
                'title',
                'guid',
            ],
        }),
        (None, {
            'fields': [
Пример #12
0
from django.core.management import call_command, CommandError
from django.test import TestCase
from django.utils._os import upath
from django.utils.six import StringIO

from yepes.apps import apps
from yepes.contrib.datamigrations import ModelMigration
from yepes.contrib.datamigrations.importation_plans.direct import DirectPlan
from yepes.contrib.datamigrations.serializers.csv import CsvSerializer
from yepes.contrib.datamigrations.serializers.json import JsonSerializer
from yepes.test_mixins import TempDirMixin

from .models import Alphabet, Author, Category, Post, Tag

PostTags = apps.get_model('datamigrations_commands_tests.post_tags')

MODULE_DIR = os.path.abspath(os.path.dirname(upath(__file__)))
MIGRATIONS_DIR = os.path.join(MODULE_DIR, 'data_migrations')


class ExportModelTest(TempDirMixin, TestCase):

    available_apps = [
        'yepes.contrib.datamigrations', 'datamigrations_commands'
    ]

    maxDiff = None
    tempDirPrefix = 'test_datamigrations_commands_'

    def test_no_label(self):
Пример #13
0
from yepes.apps import apps
from yepes.contrib.datamigrations import ModelMigration
from yepes.contrib.datamigrations.facades import (
    MultipleExportFacade,
    MultipleImportFacade,
    SingleExportFacade,
    SingleImportFacade,
)
from yepes.contrib.datamigrations.importation_plans.direct import DirectPlan
from yepes.contrib.datamigrations.serializers.csv import CsvSerializer
from yepes.contrib.datamigrations.serializers.json import JsonSerializer
from yepes.test_mixins import TempDirMixin

from .models import Alphabet, Author, Category, Post, Tag

PostTags = apps.get_model('datamigrations_facades_tests.post_tags')

MODULE_DIR = os.path.abspath(os.path.dirname(upath(__file__)))
MIGRATIONS_DIR = os.path.join(MODULE_DIR, 'data_migrations')


class MultipleExportTest(TempDirMixin, TestCase):

    available_apps = ['datamigrations_facades']

    maxDiff = None
    tempDirPrefix = 'test_datamigrations_facades_'

    def test_no_file(self):
        with self.assertRaises(TypeError):
            MultipleExportFacade.to_file_path()
Пример #14
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from yepes import admin
from yepes.apps import apps

Configuration = apps.get_model('thumbnails', 'Configuration')
Source = apps.get_model('thumbnails', 'Source')
Thumbnail = apps.get_model('thumbnails', 'Thumbnail')


class ConfigurationAdmin(admin.ModelAdmin):

    fieldsets = [
        (None, {
            'fields': [
                'key',
            ],
        }),
        (None, {
            'fields': [
                'width',
                'height',
                'background',
            ],
        }),
        (None, {
            'fields': [
                'mode',
                'algorithm',
Пример #15
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.core.exceptions import ImproperlyConfigured
from django.http import Http404
from django.utils import six
from django.utils.translation import ugettext as _

from yepes.apps import apps
from yepes.types import Undefined

Category = apps.get_model('posts', 'Category')
Tag = apps.get_model('posts', 'Tag')


class CategoryMixin(object):

    _category = Undefined
    category = None
    category_field = 'category'
    require_category = False

    def get_category(self):
        if self._category is Undefined:

            category = None
            category_pk = None
            category_slug = None
            if not self.category:
                category_pk = self.kwargs.get('category_pk')
Пример #16
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.core.files.storage import FileSystemStorage
from django.views.generic import TemplateView

from yepes.apps import apps
from yepes.views import ListView

Configuration = apps.get_model('thumbnails', 'Configuration')
SourceFile = apps.get_class('thumbnails.files', 'SourceFile')


class TestMixin(object):
    def get_context_data(self, **kwargs):
        context = super(TestMixin, self).get_context_data(**kwargs)
        context['source'] = self.get_source_file()
        return context

    def get_source_file(self):
        app_config = apps.get_app_config('thumbnails')
        app_static_dir = os.path.join(app_config.path, 'static')
        app_storage = FileSystemStorage(app_static_dir)
        media_storage = FileSystemStorage()
        path = 'thumbnails/wolf.jpg'
        if not media_storage.exists(path):
            media_storage.save(path, app_storage.open(path))
        elif app_storage.modified_time(path) > media_storage.modified_time(
                path):
            media_storage.delete(path)
Пример #17
0
 def __class__(self):
     return apps.get_model('standards', 'GeographicArea')
Пример #18
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.utils.translation import ugettext_lazy as _

from yepes import admin
from yepes.apps import apps

Country = apps.get_model('standards', 'Country')
CountrySubdivision = apps.get_model('standards', 'CountrySubdivision')
Currency = apps.get_model('standards', 'Currency')
GeographicArea = apps.get_model('standards', 'GeographicArea')
Language = apps.get_model('standards', 'Language')
Region = apps.get_model('standards', 'Region')


class CountrySubdivisionAdmin(admin.EnableableMixin, admin.ModelAdmin):

    autocomplete_lookup_fields = {
        'fk': ['country'],
        'm2m': [],
    }
    fieldsets = [
        (None, {
            'fields': [
                'country',
                'name',
                'code',
                'is_enabled',
            ],
Пример #19
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from time import time

from django import forms
from django.core.exceptions import FieldDoesNotExist
from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.translation import ugettext_lazy as _

from yepes.apps import apps
from yepes.conf import settings
from yepes.contrib.registry import registry

Comment = apps.get_model('comments', 'Comment')


class CommentForm(forms.Form):

    error_messages = {
        'invalid_honeypot':
        _('If you enter anything in this field your comment will be treated as spam.'
          ),
        'invalid_security_hash':
        _('Security hash check failed.'),
        'invalid_timestamp':
        _('Timestamp check failed'),
    }
    field_names = [
        ('timestamp', 'timestamp'),
Пример #20
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.core.cache import caches, DEFAULT_CACHE_ALIAS
from django.template import Library

from yepes.apps import apps
from yepes.template import SingleTag
from yepes.urlresolvers import full_reverse
from yepes.types import Undefined

MessageImage = apps.get_model('newsletters', 'MessageImage')
MessageLink = apps.get_model('newsletters', 'MessageLink')

register = Library()


## {% image_url name %} ########################################################


class ImageUrlTag(SingleTag):

    def process(self, name):
        if self.context.get('prerendering'):
            return "{{% {0} '{1}' %}}".format(self.tag_name, name)

        image = self.retrieve_image(name)
        if image is Undefined:
            image = MessageImage.objects.filter(name=name).first()
            self.store_image(name, image)
Пример #21
0
from django import forms
from django.conf.urls import url
from django.db import models
from django.db.models import F, Q
from django.db.models import Count
from django.utils.html import format_html
from django.utils.six.moves.urllib.parse import urljoin
from django.utils.translation import ugettext_lazy as _

from yepes import admin
from yepes.apps import apps
from yepes.conf import settings
from yepes.utils.aggregates import SumIf

Bounce = apps.get_model('newsletters', 'Bounce')
Click = apps.get_model('newsletters', 'Click')
Delivery = apps.get_model('newsletters', 'Delivery')
Domain = apps.get_model('newsletters', 'Domain')
Message = apps.get_model('newsletters', 'Message')
MessageImage = apps.get_model('newsletters', 'MessageImage')
MessageLink = apps.get_model('newsletters', 'MessageLink')
Newsletter = apps.get_model('newsletters', 'Newsletter')
Open = apps.get_model('newsletters', 'Open')
Subscriber = apps.get_model('newsletters', 'Subscriber')
SubscriberTag = apps.get_model('newsletters', 'SubscriberTag')
Subscription = apps.get_model('newsletters', 'Subscription')
Unsubscription = apps.get_model('newsletters', 'Unsubscription')
UnsubscriptionReason = apps.get_model('newsletters', 'UnsubscriptionReason')

DispatchView = apps.get_class('newsletters.views', 'DispatchView')
Пример #22
0
from django.utils import six
from django.utils.itercompat import is_iterable
from django.views.generic import (
    ArchiveIndexView,
    DayArchiveView,
    MonthArchiveView,
    YearArchiveView,
)

from yepes.apps import apps
from yepes.view_mixins import CacheMixin

BlogMixin = apps.get_class('blogs.view_mixins', 'BlogMixin')

Post = apps.get_model('posts', 'Post')


class PostArchiveIndexView(BlogMixin, CacheMixin, ArchiveIndexView):

    context_object_name = 'post_list'
    date_field = 'publish_from'
    date_list_period = 'month'
    model = Post
    require_blog = False

    def get_queryset(self):
        qs = super(PostArchiveIndexView, self).get_queryset()
        qs = qs.published(self.request.user)
        return qs
Пример #23
0
from django.utils.itercompat import is_iterable
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from django.views.generic import (
    RedirectView,
    TemplateView,
    View,
)

from yepes.apps import apps
from yepes.utils.views import decorate_view
from yepes.utils.aggregates import SumIf
from yepes.views import FormView, UpdateView

Click = apps.get_model('newsletters', 'Click')
Delivery = apps.get_model('newsletters', 'Delivery')
Message = apps.get_model('newsletters', 'Message')
Open = apps.get_model('newsletters', 'Open')
Subscriber = apps.get_model('newsletters', 'Subscriber')
Subscription = apps.get_model('newsletters', 'Subscription')

ProfileForm = apps.get_class('newsletters.forms', 'ProfileForm')
DispatchForm = apps.get_class('newsletters.forms', 'DispatchForm')
SubscriptionForm = apps.get_class('newsletters.forms', 'SubscriptionForm')
UnsubscriptionForm = apps.get_class('newsletters.forms', 'UnsubscriptionForm')
UnsubscriptionReasonForm = apps.get_class('newsletters.forms',
                                          'UnsubscriptionReasonForm')

ImageMixin = apps.get_class('newsletters.view_mixins', 'ImageMixin')
LinkMixin = apps.get_class('newsletters.view_mixins', 'LinkMixin')
Пример #24
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django import forms
from django.contrib.admin import widgets
from django.utils.translation import ugettext_lazy as _

from yepes.apps import apps
from yepes.forms import fields

Newsletter = apps.get_model('newsletters', 'Newsletter')
UnsubscriptionReason = apps.get_model('newsletters', 'UnsubscriptionReason')

FILTER_CHOICES = [
    ('', '---------'),
    ('gte', _('is greather than or equal to')),
    ('gt', _('is greather than')),
    ('exact', _('is equal to')),
    ('lt', _('is less than')),
    ('lte', _('is less than or equal to')),
]


class DispatchForm(forms.Form):

    date = forms.SplitDateTimeField(label=_('Dispatch From'),
                                    widget=widgets.AdminSplitDateTime)
    score_filter = forms.ChoiceField(choices=FILTER_CHOICES,
                                     label=_('Subscriber Score'),
                                     required=False)
Пример #25
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django import forms
from django.db import models
from django.utils.translation import ugettext_lazy as _

from yepes import admin
from yepes.apps import apps

Connection = apps.get_model('emails', 'Connection')
Delivery = apps.get_model('emails', 'Delivery')
Message = apps.get_model('emails', 'Message')


class ConnectionAdmin(admin.ModelAdmin):

    change_list_template = 'admin/change_list_filter_sidebar.html'
    change_list_filter_template = 'admin/filter_listing.html'
    fieldsets = [
        (None, {
            'fields': [
                'name',
            ],
        }),
        (_('Settings'), {
            'fields': [
                'host',
                'port',
                'username',
Пример #26
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from django.utils.translation import ugettext_lazy as _

from yepes import admin
from yepes.apps import apps

from marchena.admin import BlogModelAdmin

Author = apps.get_model('authors', 'Author')


class AuthorMixin(object):

    blog_field = 'blogs'
    fieldsets = [
        (None, {
            'fields': [
                'first_name',
                'last_name',
                'admin_username',
                'email',
            ],
        }),
    ]
    list_display = ['admin_full_name', 'admin_username', 'email']
    list_filter = ['is_staff', 'is_superuser', 'is_active']
    ordering = ['first_name', 'last_name']
    readonly_fields = ['admin_username']
Пример #27
0
import calendar
from datetime import datetime, timedelta

from django.core.urlresolvers import reverse
from django.db.models import Count
from django.template import Library
from django.template.defaultfilters import date as date_format
from django.utils import six
from django.utils import timezone
from django.utils.decorators import classonlymethod

from yepes.apps import apps
from yepes.template import AssignTag, InclusionTag, SingleTag
from yepes.template import MultipleObjectMixin, SingleObjectMixin

Author = apps.get_model('authors', 'Author')
Category = apps.get_model('posts', 'Category')
Post = apps.get_model('posts', 'Post')
Tag = apps.get_model('posts', 'Tag')

register = Library()

## {% calendar[ year[ month[ user]]] %} ########################################


class CalendarTag(MultipleObjectMixin, InclusionTag):

    model = Post
    template = 'partials/calendar.html'

    def get_posts_by_publication_day(self, first_date, last_date, user=None):
Пример #28
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from yepes.apps import apps
from yepes.view_mixins import CanonicalMixin
from yepes.views import ListView

BlogMixin = apps.get_class('blogs.view_mixins', 'BlogMixin')
PostListView = apps.get_class('posts.views', 'PostListView')

Blog = apps.get_model('blogs', 'Blog')


class BlogDetailView(BlogMixin, CanonicalMixin, PostListView):
    """
    Displays a list of published posts that belong to the given blog.
    """
    require_blog = True

    def get_canonical_path(self, request):
        blog = self.get_blog()
        return blog.get_absolute_url()

    def get_template_names(self):
        names = super(BlogDetailView, self).get_template_names()
        blog = self.get_blog()
        if blog is not None:
            names.insert(
                -1, '{0}/{1}_detail.html'.format(
                    blog._meta.app_label,
Пример #29
0
# -*- coding:utf-8 -*-

from __future__ import unicode_literals

from yepes.apps import apps
from yepes.conf import settings
from yepes.views import ListView

from marchena.modules.blogs.view_mixins import BlogMixin
from marchena.modules.links.view_mixins import LinkCategoryMixin

Link = apps.get_model('links', 'Link')
LinkCategory = apps.get_model('links', 'LinkCategory')


class LinksOpmlView(BlogMixin, LinkCategoryMixin, ListView):

    content_type = 'application/xml'
    link_category_field = 'pk'
    model = LinkCategory
    require_blog = settings.BLOG_MULTIPLE
    require_link_category = False
    template_name = 'links_opml.xml'

    def get_queryset(self):
        qs = super(LinksOpmlView, self).get_queryset()
        qs = qs.prefetch_related('links')
        return qs

Пример #30
0
from __future__ import unicode_literals

from django.utils.html import format_html
from django.utils.six.moves.urllib.parse import urljoin
from django.utils.translation import (
    ugettext,
    ugettext_lazy as _,
)

from yepes import admin
from yepes.apps import apps
from yepes.conf import settings

from marchena.admin import BlogModelAdmin

Comment = apps.get_model('comments', 'Comment')
CommentStatus = apps.get_model('comments', 'CommentStatus')


class CommentMixin(object):

    blog_field = 'post__blog'

    date_hierarchy = 'creation_date'
    fieldsets = [
        (None, {
            'fields': [
                'status',
                'content',
            ],
        }),