Search code examples
wagtail

Wagtail CMS in multi languages : How to diplaying 3 latest items in home page


When I create content, I have its equivalent in the languages ​​added to my site in the DB. So how to display only the last 3 articles of a single language on the home page using "ojects.all().order_by('-date')[:3]"

def get_context(self, request):
    # Update context to include only published posts, ordered by reverse-chron
    context = super().get_context(request)
    latest_insights = Insight.objects.all().order_by('-date')[:3]
    context['latest_insights'] = latest_insights
    return context

Solution

  • Answer to the question regarding filtering choice lists by locale:

    This is a general use FieldPanel for any single or multi choice widget that targets a translated model for the choice queryset. It limits the choices to only those from the same locale as the object being edited (i.e. if the edited page is Spanish, choices are limited to Spanish translations) - this is independent of the locale the editor uses for the admin interface.

    from django.core.exceptions import ImproperlyConfigured
    from django.forms.models import ModelChoiceIterator
    from django.forms.widgets import (
        CheckboxSelectMultiple,
        RadioSelect,
        Select,
        SelectMultiple,
    )
    from django.utils.translation import gettext_lazy as _
    from wagtail.admin.panels import FieldPanel
    
    
    class LocalizedSelectPanel(FieldPanel):
        """
        Customised FieldPanel to filter choices based on locale of page/model being created/edited
        Usage:
        widget_class - optional, override field widget type
                     - should be CheckboxSelectMultiple, RadioSelect, Select or SelectMultiple
        typed_choice_field - set to True with Select widget forces drop down list with selector icon
        """
    
        def __init__(
            self, field_name, widget_class=None, typed_choice_field=False, *args, **kwargs
        ):
            if not widget_class in [
                None,
                CheckboxSelectMultiple,
                RadioSelect,
                Select,
                SelectMultiple,
            ]:
                raise ImproperlyConfigured(
                    _(
                        "widget_class should be a Django form widget class of type "
                        "CheckboxSelectMultiple, RadioSelect, Select or SelectMultiple"
                    )
                )
            self.widget_class = widget_class
            self.typed_choice_field = typed_choice_field
            super().__init__(field_name, *args, **kwargs)
    
        def clone_kwargs(self):
            return {
                "heading": self.heading,
                "classname": self.classname,
                "help_text": self.help_text,
                "widget_class": self.widget_class,
                "typed_choice_field": self.typed_choice_field,
                "field_name": self.field_name,
            }
    
        class BoundPanel(FieldPanel.BoundPanel):
            def __init__(self, **kwargs):
                super().__init__(**kwargs)
                if not self.panel.widget_class:
                    self.form.fields[self.field_name].widget.choices = self.choice_list
                else:
                    self.form.fields[self.field_name].widget = self.panel.widget_class(
                        choices=self.choice_list
                    )
                if self.panel.typed_choice_field:
                    self.form.fields[
                        self.field_name
                    ].__class__.__name__ = "typed_choice_field"
                pass
    
            @property
            def choice_list(self):
                self.form.fields[self.field_name].queryset = self.form.fields[
                    self.field_name
                ].queryset.filter(locale_id=self.instance.locale_id)
                return ModelChoiceIterator(self.form.fields[self.field_name])
    

    Example use:

        categories = ParentalManyToManyField(
            "blog.BlogCategory",
            verbose_name=_("Blog Categories"),
            related_name="categories",
        )
        content_panels = Page.content_panels + [
             ....
             LocalizedSelectPanel('categories', CheckboxSelectMultiple)
        ]