【问题标题】:Is it possible to order a Django Model using the active language?是否可以使用活动语言订购 Django 模型?
【发布时间】:2013-04-18 14:50:30
【问题描述】:

我正在使用 Django 1.5.1,我想知道以下问题:是否可以使用 django-transmeta 并使用用户正在访问管理员的活动语言在可翻译字段的模型中定义排序?

到目前为止,我实现了使用已翻译字段并使用默认语言而不是活动语言进行排序,因为如果我从 Meta 类调用方法,对get_language() 的调用总是返回settings.py 中定义的默认值(或来自 ModelAdmin 类)。

这是我正在处理的代码,感谢您的帮助:

class StartupType(models.Model):

    __metaclass__ = TransMeta

    name = models.CharField(_("Name"), max_length=30, unique=True)
    slug = models.SlugField(_("Slug"), max_length=30, unique=True, editable=False)

    class Meta:

        verbose_name = _("Startup type")
        verbose_name_plural = _("Startup types")
        translate = (
            "name",
        )
        ordering = [
            "name_" + LANGUAGE_CODE,
        ]

【问题讨论】:

    标签: python django django-models internationalization


    【解决方案1】:

    根据documentation,您可以定义一个get_ordering() 方法来使用动态订单:

    # admin.py
    from django.contrib import admin
    from .models import StartupType
    
    class StartupTypeAdmin(admin.ModelAdmin):
        def get_ordering(self, request):
            language_code = request.LANGUAGE_CODE[:2]
            return ('name_%s' % language_code,)
    
    admin.site.register(StartupType, StartupTypeAdmin)
    

    使用get_language() 代替request.LANGUAGE_CODE 也可以。

    如果您仍然没有获得正确的语言,请确保您在settings.py 中的 Session 中间件之后添加了 Locale 中间件,例如:

    MIDDLEWARE_CLASSES = ( 
        'django.middleware.common.CommonMiddleware', 
        'django.contrib.sessions.middleware.SessionMiddleware', 
        'django.middleware.locale.LocaleMiddleware', 
        'django.middleware.csrf.CsrfViewMiddleware', 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        'django.contrib.messages.middleware.MessageMiddleware', 
        'django.middleware.clickjacking.XFrameOptionsMiddleware', 
    ) 
    

    编辑:添加了在模型上定义动态排序的替代方法。

    如果您还想在模型类上设置ordering,这似乎有点复杂,这是我能想到的最好的:

    from django.db import models
    from django.db.models.options import Options
    from django.utils.translation import get_language
    from django.utils.translation import ugettext_lazy as _
    
    from transmeta import TransMeta, get_real_fieldname
    
    
    class TranslatedOptions(Options):
        @property
        def ordering(self):
            lang = get_language()[:2]
            return [get_real_fieldname(f, lang) for f in self.orig_ordering]
    
        @ordering.setter
        def ordering(self, value):
            self.orig_ordering = value
    
    
    class TransMetaOrdering(TransMeta):
        def __new__(cls, name, bases, attrs):
            new_class = super(TransMetaOrdering, cls).__new__(cls, name, bases, attrs)
            options = TranslatedOptions(None)
            for k, v in new_class._meta.__dict__.iteritems():
                setattr(options, k, v)
            new_class._meta = options
            return new_class
    
    
    class StartupType(models.Model):
        __metaclass__ = TransMetaOrdering
    
        name = models.CharField(_("Name"), max_length=30)
        slug = models.SlugField(_("Slug"), max_length=30, editable=False)
    
        class Meta:
            verbose_name = _("Startup type")
            verbose_name_plural = _("Startup types")
            translate = (
                "name",
            )
            ordering = (
                "name",
            )
    

    这会将StartupType._metadjango.db.models.options.Options 类型的对象)替换为TranslatedOptions 类型的新对象,它将ordering 作为动态属性公开。

    【讨论】:

    • 嗨,NCao!我尝试使用get_ordering(),效果很好! :) 我还在Session 之后修复了Locale 中间件中的顺序。有没有办法在 Model 而不是 ModelAdmin 中指定“基于活动语言的动态排序”?我还尝试将get_language() 用于search_fields,但它总是返回默认语言,而不是活动语言:(你对这些主题有什么想法吗?谢谢!:)
    • @Caumons 实际上可以在模型上定义动态排序,虽然相当复杂,所以将动态部分委托给视图可能更容易。至于search_fields,我相信ModelAdmin 上的一个简单属性会起作用。它将在ModelAdmin.changelist_view 内进行评估,因此根据需要使用当前语言。
    • 感谢您的回答!没错,直接在Model中设置ordering太复杂了,还是把它移到对应的views上会好很多。我使用属性尝试了您对search_fields 的建议,但恐怕该字段不允许使用可调用对象。所以我认为这是不可能的,只能搜索一种语言(默认)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2015-03-14
    • 2013-06-17
    • 2017-03-26
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多