【问题标题】:django load object name by languagedjango 按语言加载对象名称
【发布时间】:2014-09-10 19:04:10
【问题描述】:

我有这样定义的模型

class Foo(Model):
    id = AutoField(primary_key = True)
    code = CharField(blank = False, unique = False, max_length =  64)

class FooName(Model):
    id = AutoField(primary_key = True)
    foo = ForeignKey(Foo, blank = False, related_name = '+')
    language = CharField(blank = False, max_length = 16)
    value = CharField(blank = False, max_length = 256)

class Bar(Model):
    id = AutoField(primary_key = True)
    foo = ForeignKey(Foo, blank = False, related_name = '+')

所以,对于 'foo' 表这样的

{ 1, 'apple' },
{ 1, 'pear' }

我有 'fooname' 表,比如

{ 1, 1, 'en', 'Apple'},
{ 2, 1, 'fr', 'Pomme'},
{ 3, 2, 'en', 'Pear'},
{ 4, 2, 'fr', 'Poire'}

当然,我将 request.LANGUAGE 设置为有意义的东西。

问题是:如何将 Foo 模型上的 name 属性动态评估为本地化名称,即类似

self.name = FooName.objects.get(foo = self, language = request.LANGUAGE)

但没有明确传递请求对象?

我的意思是,如果我有 Bar 的集合,我想写一些类似的东西

for bar in Bar.objects.filter(...):
    fn = bar.foo.name

不需要复杂的语言匹配(使用 'en' 表示 'en-US')或回退(如果当前语言没有值,则使用 'en-US')逻辑。

【问题讨论】:

  • 您是否需要使用这些值填充一些下拉列表?如果是这样,您可以在视图中进行此查询并通过设置 queryset 属性填充表单。
  • @AnkitJaiswal 不仅是下拉菜单,还有列表、表格甚至单个项目

标签: django django-models django-1.7


【解决方案1】:

为什么你不能这样做?

for bar in Bar.objects.filter(...):
    fn = FooName.objects.get(foo=bar.foo, language=request.LANGUAGE).value

【讨论】:

  • 因为我不能在模板中这样做,我不想在表单中这样做。
  • @adontz 为什么不能在视图中执行此操作?
  • @AnkitJaiswal 因为这意味着 View 应该知道表单模板需要哪些字段(而不是对象)。这增加了耦合。
【解决方案2】:

如果您想在模板中执行此操作,您需要一个自定义模板标签。在此您可以访问请求对象。您可以提取语言并将其传递给模型实例方法。

# models.py
from django.db import models


class Foo(models.Model):
    code = models.CharField(blank=False, max_length=64)

    def get_name(self, language_code):
        return self.foo_set.filter(language=language).get()

class FooName(Model):
    foo = models.ForeignKey(Foo)
    language = models.CharField(max_length=16)
    value = models.CharField(max_length=255)

# templatetages/mytags.py
from django import template

register = template.Library()

@register.simple_tag(takes_context=True)
def resolve_foo_name(context, foo_object):
    return foo_object.get_name(context.LANGUAGE)


# template.html
{% load mytags %}
{% resolve_foo_name foo_object %}

【讨论】:

    猜你喜欢
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2022-11-10
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多