Exemple #1
0
class SupernautMenu(Menu):
    home = MenuItem(url='/', display_name=_('Home'))
    artists = MenuItem(display_name=_('Artists'))
    albums = MenuItem(display_name=_('Albums'))
    tracks = MenuItem(display_name=_('Tracks'))

    class Meta:
        attrs__class = {'fixed-top': True}
Exemple #2
0
 class MyMenu(Menu):
     sub_menu1 = MenuItem(url='foo',
                          sub_menu=dict(bar=MenuItem(),
                                        foo=MenuItem(url='baz')))
     sub_menu2 = MenuItem(url='foo',
                          sub_menu=dict(bar=MenuItem(),
                                        foo=MenuItem(url='baz')))
     sub_menu3 = MenuItem(url='bar',
                          sub_menu=dict(bar=MenuItem(),
                                        foo=MenuItem(url='baz')))
Exemple #3
0
 class FooPage(Page):
     menu = Menu(sub_menu=dict(
         root=MenuItem(url='/'),
         menu_test=MenuItem(),
         f_a_1=MenuItem(display_name='Example 1: echo submitted data',
                        url="form_example_1/"),
         f_a_2=MenuItem(display_name='Example 2: create a Foo',
                        url="form_example_2/"),
         f_a_3=MenuItem(display_name='Example 3: edit a Foo',
                        url="form_example_3/"),
         f_a_4=MenuItem(display_name='Example 4: custom buttons',
                        url="form_example_4/"),
         f_a_5=MenuItem(display_name='Example 5: automatic AJAX endpoint',
                        url="form_example_5/"),
         f_a_k=MenuItem(display_name='Kitchen sink', url="form_kitchen/"),
     ), )
Exemple #4
0
class Admin(Page):
    class Meta:
        iommi_style = 'bootstrap'
        table_class = Table
        form_class = Form
        apps__auth_user__include = True
        apps__auth_group__include = True
        parts__messages = Messages()
        parts__list_auth_user = dict(
            auto__include=['username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active', 'is_superuser'],
            columns=dict(
                username__filter__freetext=True,
                email__filter__freetext=True,
                first_name__filter__freetext=True,
                last_name__filter__freetext=True,
                is_staff__filter__include=True,
                is_active__filter__include=True,
                is_superuser__filter__include=True,
            ),
        )

    table_class: Type[Table] = Refinable()
    form_class: Type[Form] = Refinable()

    apps: Namespace = Refinable()  # Global configuration on apps level

    menu = Menu(
        sub_menu=dict(
            root=MenuItem(url=lambda admin, **_: reverse(admin.__class__.all_models), display_name=gettext('iommi administration')),
            change_password=MenuItem(url=lambda **_: reverse(Auth.change_password), display_name=gettext('Change password')),
            logout=MenuItem(url=lambda **_: reverse(Auth.logout), display_name=gettext('Logout')),
        ),
    )

    @read_config
    @reinvokable
    @dispatch(
        apps=EMPTY,
        parts=EMPTY,
    )
    def __init__(self, parts, apps, **kwargs):
        # Validate apps params
        for k in apps.keys():
            assert k in joined_app_name_and_model, f'{k} is not a valid app/model key.\n\nValid keys:\n    ' + '\n    '.join(joined_app_name_and_model)

        def should_throw_away(k, v):
            if isinstance(v, Namespace) and 'call_target' in v:
                return False

            if k == 'all_models':
                return True

            prefix_blacklist = [
                'list_',
                'delete_',
                'create_',
                'edit_',
            ]
            for prefix in prefix_blacklist:
                if k.startswith(prefix):
                    return True

            return False

        parts = {
            # Arguments that are not for us needs to be thrown on the ground
            k: None if should_throw_away(k, v) else v
            for k, v in items(parts)
        }

        super(Admin, self).__init__(parts=parts, apps=apps, **kwargs)

    @staticmethod
    def has_permission(request, operation, model=None, instance=None):
        return request.user.is_staff

    def own_evaluate_parameters(self):
        return dict(admin=self, **super(Admin, self).own_evaluate_parameters())

    @classmethod
    @class_shortcut(
        table=EMPTY,
        table__call_target__attribute='div',
    )
    @require_login
    def all_models(cls, request, table, call_target=None, **kwargs):
        if not cls.has_permission(request, operation='all_models'):
            raise Http404()

        def rows(admin, **_):

            for app_name, models in items(django_apps.all_models):
                has_yielded_header = False

                for model_name, model in sorted(items(models), key=lambda x: x[1]._meta.verbose_name_plural):
                    if not admin.apps.get(f'{app_name}_{model_name}', {}).get('include', False):
                        continue

                    if not has_yielded_header:
                        yield Struct(
                            name=app_verbose_name_by_label[app_name],
                            verbose_app_name=app_verbose_name_by_label[app_name],
                            url=None,
                            format=lambda row, table, **_: Header(row.name, _name='invalid_name').bind(parent=table).__html__()
                        )
                        has_yielded_header = True

                    yield Struct(
                        verbose_app_name=app_verbose_name_by_label[app_name],
                        app_name=app_name,
                        name=model._meta.verbose_name_plural.capitalize(),
                        url='%s/%s/' % (app_name, model_name),
                        format=lambda row, **_: row.name,
                    )

        table = setdefaults_path(
            Namespace(),
            table,
            title=gettext('All models'),
            call_target__cls=cls.get_meta().table_class,
            sortable=False,
            rows=rows,
            header__template=None,
            page_size=None,
            columns__name=dict(
                cell__url=lambda row, **_: row.url,
                display_name='',
                cell__format=lambda row, **kwargs: row.format(row=row, **kwargs),
            ),
        )

        return call_target(
            parts__all_models=table,
            **kwargs
        )

    @classmethod
    @class_shortcut(
        table=EMPTY,
    )
    @require_login
    def list(cls, request, app_name, model_name, table, call_target=None, **kwargs):
        model = django_apps.all_models[app_name][model_name]

        if not cls.has_permission(request, operation='list', model=model):
            raise Http404()

        table = setdefaults_path(
            Namespace(),
            table,
            call_target__cls=cls.get_meta().table_class,
            auto__model=model,
            columns=dict(
                select__include=True,
                edit=dict(
                    call_target__attribute='edit',
                    after=0,
                    cell__url=lambda row, **_: '%s/edit/' % row.pk,
                ),
                delete=dict(
                    call_target__attribute='delete',
                    after=LAST,
                    cell__url=lambda row, **_: '%s/delete/' % row.pk,
                ),
            ),
            actions=dict(
                create=dict(
                    display_name=gettext('Create %(model_name)s') % dict(model_name=model._meta.verbose_name),
                    attrs__href='create/',
                ),
            ),
            query_from_indexes=True,
            bulk__actions__delete__include=True,
        )

        return call_target(
            parts__header__children__link__attrs__href='../..',
            **{f'parts__list_{app_name}_{model_name}': table},
            **kwargs,
        )

    @classmethod
    @class_shortcut(
        form=EMPTY,
    )
    @require_login
    def crud(cls, request, operation, form, app_name, model_name, pk=None, call_target=None, **kwargs):
        model = django_apps.all_models[app_name][model_name]
        instance = model.objects.get(pk=pk) if pk is not None else None

        if not cls.has_permission(request, operation=operation, model=model, instance=instance):
            raise Http404()

        def on_save(form, instance, **_):
            message = f'{form.model._meta.verbose_name.capitalize()} {instance} was ' + ('created' if form.extra.is_create else 'updated')
            messages.add_message(request, messages.INFO, message, fail_silently=True)

        def on_delete(form, instance, **_):
            message = f'{form.model._meta.verbose_name.capitalize()} {instance} was deleted'
            messages.add_message(request, messages.INFO, message, fail_silently=True)

        form = setdefaults_path(
            Namespace(),
            form,
            call_target__cls=cls.get_meta().form_class,
            auto__instance=instance,
            auto__model=model,
            call_target__attribute=operation,
            extra__on_save=on_save,
            extra__on_delete=on_delete,
        )

        return call_target(
            **{f'parts__{operation}_{app_name}_{model_name}': form},
            **kwargs,
        )

    @classmethod
    @class_shortcut(
        call_target__attribute='crud',
        operation='create',
        parts__header__children__link__attrs__href='../../..',
    )
    def create(cls, request, call_target, **kwargs):
        return call_target(request=request, **kwargs)

    @classmethod
    @class_shortcut(
        call_target__attribute='crud',
        operation='edit',
        parts__header__children__link__attrs__href='../../../..',
    )
    def edit(cls, request, call_target, **kwargs):
        return call_target(request=request, **kwargs)

    @classmethod
    @class_shortcut(
        call_target__attribute='crud',
        operation='delete',
        parts__header__children__link__attrs__href='../../../..',
    )
    def delete(cls, request, call_target, **kwargs):
        return call_target(request=request, **kwargs)

    @classmethod
    def urls(cls):
        return Struct(
            urlpatterns=[
                            path('', cls.all_models),
                            path('<app_name>/<model_name>/', cls.list),
                            path('<app_name>/<model_name>/create/', cls.create),
                            path('<app_name>/<model_name>/<int:pk>/edit/', cls.edit),
                            path('<app_name>/<model_name>/<int:pk>/delete/', cls.delete),
                        ] + Auth.urls().urlpatterns
        )
Exemple #5
0
 class MyMenu(Menu):
     sub_menu1 = MenuItem(url='foo', sub_menu=dict(bar=MenuItem(), external=MenuItem(url='http://example.com'), foo=MenuItem(url='baz')))
     sub_menu2 = MenuItem(url='foo', sub_menu=dict(bar=MenuItem(), external=MenuItem(url='http://example.com'), foo=MenuItem(url='baz')))
     sub_menu3 = MenuItem(url='bar', sub_menu=dict(bar=MenuItem(), external=MenuItem(url='http://example.com'), foo=MenuItem(url='baz')))
     external = MenuItem(url='http://example.com')
Exemple #6
0
def test_template():
    menu = Menu(
        template=Template('{{ menu.sub_menu.foo.display_name }}'),
        sub_menu=dict(foo=MenuItem())
    ).bind(request=req('get'))
    assert menu.__html__() == 'Foo'
Exemple #7
0
 class MyMenu(Menu):
     sub_menu = MenuItem(url=None, sub_menu=dict(bar=MenuItem(), foo=MenuItem(after=0)))
Exemple #8
0
 class MyMenu(Menu):
     home = MenuItem(url='/')
     artists = MenuItem()
     albums = MenuItem()
     external = MenuItem(url='http://example.com')
     songs = MenuItem()
Exemple #9
0
 class MyMenu(Menu):
     home = MenuItem(url='/')
     artists = MenuItem()
     albums = MenuItem(include=False)
     empty_sub_menu = MenuItem(url=None, sub_menu=dict(foo=MenuItem(include=False)))
Exemple #10
0
 class MyMenu(Menu):
     foo = MenuItem(url=reverse_lazy('reverse-lazy-test'))
Exemple #11
0
 class MyPage(Page):
     menu = Menu(sub_menu=dict(root=MenuItem()))