Aller au contenu

# Mixins

### `TabedViewMixin`

Bases: `View`

Basic functions for displaying tabs in the template.

### `AllowFragment`

Add `is_fragment` to templates. It's only True if the request is emitted by htmx

### `FragmentMixin`

Bases: `TemplateResponseMixin`, `ContextMixin`

Make a view buildable as a fragment that can be embedded in a template.

Most fragments are used in two different ways : - in the request/response cycle, like any regular view - in templates, where the rendering is done in another view

This mixin aims to simplify the initial fragment rendering. The rendered fragment will then be able to re-render itself through the request/response cycle if it uses HTMX.

Example

    class MyFragment(FragmentMixin, FormView):
        template_name = "app/fragment.jinja"
        form_class = MyForm
        success_url = reverse_lazy("foo:bar")

    # in another view :
    def some_view(request):
        fragment = MyFragment.as_fragment()
        return render(
            request,
            "app/template.jinja",
            context={"fragment": fragment(request)
        }

    # in urls.py
    urlpatterns = [
        path("foo/view", some_view),
        path("foo/fragment", MyFragment.as_view()),
    ]

#### `reload_on_redirect = False` `class-attribute` `instance-attribute`

If True, this fragment will trigger a full page reload on redirect.

### `UseFragmentsMixin`

Bases: `ContextMixin`

Mark a view as using fragments.

This mixin is not mandatory (you may as well render manually your fragments in the `get_context_data` method). However, the interface of this class bring some distinction between fragments and other context data, which may reduce boilerplate.

Example

    class FooFragment(FragmentMixin, FormView): ...

    class BarFragment(FragmentMixin, FormView): ...

    class AdminFragment(FragmentMixin, FormView): ...

    class MyView(UseFragmentsMixin, TemplateView)
        template_name = "app/view.jinja"
        fragments = {
            "foo": FooFragment
            "bar": BarFragment(template_name="some_template.jinja")
        }
        fragments_data = {
            "foo": {"some": "data"}  # this will be passed to the FooFragment renderer
        }

        def get_fragments(self):
            res = super().get_fragments()
            if self.request.user.is_superuser:
                res["admin_fragment"] = AdminFragment
            return res

#### `get_fragment_data()`

Return eventual data used to initialize the fragments.

Source code in `core/views/mixins.py`

    179
    180
    181
    def get_fragment_data(self) -> dict[str, dict[str, Any]]:
        """Return eventual data used to initialize the fragments."""
        return self.fragment_data if self.fragment_data is not None else {}

#### `get_fragment_context_data()`

Return the rendered fragments as context data.

Source code in `core/views/mixins.py`

    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    def get_fragment_context_data(self) -> dict[str, SafeString]:
        """Return the rendered fragments as context data."""
        res = {}
        data = self.get_fragment_data()
        for name, fragment in self.get_fragments().items():
            is_cls = inspect.isclass(fragment) and issubclass(fragment, FragmentMixin)
            _fragment = fragment.as_fragment() if is_cls else fragment
            fragment_data = data.get(name, {})
            res[name] = _fragment(self.request, **fragment_data)
        return res