سؤال

ودعونا نقول لدي نموذج جانغو التالية:

class StandardLabel(models.Model):
    id = models.AutoField(primary_key=True)
    label = models.CharField(max_length=255)
    abbreviation = models.CharField(max_length=255)

وكل تسمية لديه رقم الهوية، ونص التسمية، واختصار. الآن، أريد أن يكون هذه التسميات للترجمة إلى لغات أخرى. ما هي أفضل طريقة للقيام بذلك؟

وكما أرى، ولدي عدد قليل من الخيارات:

1: إضافة ترجمة كحقول على نموذج:

class StandardLabel(models.Model):
    id = models.AutoField(primary_key=True)
    label_english = models.CharField(max_length=255)
    abbreviation_english = models.CharField(max_length=255)
    label_spanish = models.CharField(max_length=255)
    abbreviation_spanish = models.CharField(max_length=255)

ومن الواضح أن هذا ليس مثاليا - إضافة لغات يتطلب تحرير نموذج يعتمد اسم الحقل الصحيح على لغة

2: إضافة اللغة كمفتاح خارجي:

class StandardLabel(models.Model):
    id = models.AutoField(primary_key=True)
    label = models.CharField(max_length=255)
    abbreviation = models.CharField(max_length=255)
    language = models.ForeignKey('languages.Language')

وهذا هو أفضل بكثير، والآن يمكنني أن أسأل لجميع تسميات مع لغة معينة، ورمى بها إلى ديكت:

labels = StandardLabel.objects.filter(language=1)
labels = dict((x.pk, x) for x in labels)

ولكن المشكلة هنا هي أن ديكت تسميات من المفترض أن تكون طاولة البحث، كما يلي:

x = OtherObjectWithAReferenceToTheseLabels.object.get(pk=3)
thelabel = labels[x.labelIdNumber].label

والذي لا يعمل إذا كان هناك خلاف في التسمية، ربما مع لغات متعددة لتسمية واحدة. حل هذه واحدة، ولست بحاجة حقل آخر:

class StandardLabel(models.Model):
    id = models.AutoField(primary_key=True)
    group_id = models.IntegerField(db_index=True)
    label = models.CharField(max_length=255)
    abbreviation = models.CharField(max_length=255)
    language = models.ForeignKey('languages.Language')
    class Meta:
        unique_together=(("group_id", "language"),)
#and I need to group them differently:
labels = StandardLabel.objects.filter(language=1)
labels = dict((x.group_id, x) for x in labels)

و3: رمي تسمية نص للخروج الى نموذج جديد:

class StandardLabel(models.Model):
    id = models.AutoField(primary_key=True)
    text = models.ManyToManyField('LabelText')

class LabelText(models.Model):
    id = models.AutoField(primary_key=True)
    label = models.CharField(max_length=255)
    abbreviation = models.CharField(max_length=255)
    language = models.ForeignKey('languages.Language')

labels = StandardLabel.objects.filter(text__language=1)
labels = dict((x.pk, x) for x in labels)

ولكن بعد ذلك لم ينجح هذا الإجراء، ويسبب قاعدة بيانات ضرب في كل مرة كنت مرجع النص التسمية:

x = OtherObjectWithAReferenceToTheseLabels.object.get(pk=3)
thelabel = labels[x.labelIdNumber].text.get(language=1)

ولقد نفذت الخيار 2، ولكن أجد أنه قبيح جدا - أنا لا أحب هذا المجال group_id، وأنا لا أستطيع التفكير في أي شيء أفضل لتسميته. وبالإضافة إلى ذلك، StandardLabel وأنا أستخدم ذلك هو النموذج المجرد، وأنا فرعية للحصول على مجموعات تسمية مختلفة لمختلف المجالات.

وأفترض أنه إذا لم الخيار 3 / لا / ضرب قاعدة البيانات، وهذا ما سأختار. وأعتقد أن المشكلة الحقيقية هي أن text__language=1 التصفية لا بالتخزين المؤقت الحالات LabelText، وهكذا هو DB ضرب عندما text.get(language=1)

ما هي أفكارك حول هذا؟ يمكن لأي شخص أن يوصي حل أنظف؟

تعديل : في فقط أن نوضح أن هذه ليست تشكيل تسميات، لذلك لا يساعد النظام بفك التدويل

هل كانت مفيدة؟

المحلول

ويهمني كثيرا يفضل إضافة حقل لكل لغة من مثيل النموذج الجديد لكل لغة. أنها لا تتطلب مخطط تغيير عند إضافة لغة جديدة، ولكن هذا ليس من الصعب، وكيف وغالبا ما كنت تتوقع إضافة لغات؟ في هذه الأثناء، وأنها سوف تعطيك أداء قاعدة البيانات أفضل (أي أضاف ينضم أو فهارس) ولم يكن لديك إلى الوحل حتى المنطق الاستعلام الخاص بك مع الاشياء الترجمة؛ إبقاء كل شيء في قوالب حيث تنتمي.

وحتى أفضل، واستخدام التطبيقات التي يمكن إعادة استخدامها مثل جانغو-transmeta أو <ل أ href = "http://code.google.com/p/django-modeltranslation/" يختلط = "نوفولو noreferrer"> جانغو-modeltranslation أن يجعل هذا بسيط غبي وتقريبا شفافة تماما.

نصائح أخرى

وثمة خيار آخر قد ترغب في النظر، وهذا يتوقف على تصميم التطبيق الخاص بك وبطبيعة الحال، هو الاستفادة من الميزات تدويل جانغو. النهج التي يستخدمونها هو أمر شائع جدا لنهج وجدت في برامج سطح المكتب.

وأرى تم تحرير المسألة لإضافة إشارة إلى جانغو التدويل، لذلك لم نعرف عن ذلك، ولكن ملامح تي في جانغو تنطبق على أكثر بكثير من النماذج فقط. انها touchs الكثير جدا، ويحتاج سوى عدد قليل من القرص لتصميم التطبيق الخاص بك.

ومستندات تلك هي هنا: HTTP: //docs.djangoproject كوم / EN / ديف / المواضيع / I18N / # موضوعات I18N

والفكرة هي أن تقوم بتعريف النموذج الخاص بك كما لو كان هناك لغة واحدة فقط. وبعبارة أخرى، وجعل أي إشارة إلى لغة على الإطلاق، ووضع فقط، مثلا، اللغة الإنجليزية في النموذج.

وهكذا:

class StandardLabel(models.Model):
    abbreviation = models.CharField(max_length=255)
    label = models.CharField(max_length=255)

وأعرف أن هذا يبدو وكأنه كنت قد القيت تماما من مسألة اللغة، ولكن كنت قد الواقع مجرد نقل ذلك. بدلا من لغة يجري في نموذج البيانات الخاص بك، وكنت قد دفعها إلى طريقة العرض.

والميزات جانغو تدويل تسمح لك لإنشاء ملفات ترجمة النصوص، ويوفر عددا من المزايا لسحب النص من النظام في الملفات. هذا هو في الواقع مفيدة للغاية لأنه يسمح لك لإرسال الملفات العادي إلى المترجم الخاص بك، مما يجعل مهمتهم أسهل. إضافة لغة جديدة سهلا كما هو الحصول على ملف ترجمتها إلى لغة جديدة.

وملفات الترجمة تحدد تسمية من قاعدة البيانات، وترجمة لتلك اللغة. هناك وظائف للتعامل مع الترجمة بشكل حيوي في وقت التشغيل لنماذج، وجهات النظر المشرف، وجافا سكريبت، والقوالب.

وعلى سبيل المثال، في قالب، قد تفعل شيئا مثل:

<b>Hello {% trans "Here's the string in english" %}</b>

وأو في التعليمات البرمجية الرأي، هل يمكن أن تفعل:

# See docs on setting language, or getting Django to auto-set language
s = StandardLabel.objects.get(id=1)
lang_specific_label = ugettext(s.label)

وبطبيعة الحال، إذا كان التطبيق هو كل شيء عن دخول لغات جديدة on the fly، فإن هذا النهج قد لا عمل لك. ومع ذلك، إلقاء نظرة على مشروع التدويل كما قد يكون إما قادرا على استخدامها "كما هي"، أو تكون مصدر إلهام لحل جانغو المناسب أن يعمل للمجال الخاص بك.

وأود أن إبقاء الأمور بسيطة بقدر الإمكان. فإن البحث سيكون أسرع وأنظف الرمز مع شيء من هذا القبيل:

class StandardLabel(models.Model):
    abbreviation = models.CharField(max_length=255)
    label = models.CharField(max_length=255)
    language = models.CharField(max_length=2)
    # or, alternately, specify language as a foreign key:
    #language = models.ForeignKey(Language)

    class Meta:
        unique_together = ('language', 'abbreviation')

وبعد ذلك المستند إلى استعلام على الاختصار واللغة:

l = StandardLabel.objects.get(language='en', abbreviation='suite')

وعلى الرغم من أنني سوف أذهب مع دانيال حل ، هنا هو بديل من ما كنت يفهم من تعليقاتكم:

ويمكنك استخدام XMLField أو JSONField ل متجرك أزواج الانجليزية / الترجمة. هذا من شأنه أن يسمح الأشياء الخاصة بك الرجوع التسميات لاستخدام id احد لجميع الترجمات. ثم هل يمكن أن يكون وسيلة مدير مخصص للاتصال ترجمة محددة:

Label.objects.get_by_language('ru', **kwargs)

وأو أن حل أنظف قليلا وقليلا أكثر تعقيدا أن يلعب بشكل جيد مع admin يكون لإلغاء تطبيع وXMLField إلى نموذج آخر مع العديد من الى واحد العلاقة إلى نموذج Label. API نفسه، ولكن بدلا من تحليل XML يمكن أن الاستعلام النماذج ذات الصلة.

لكلا اقتراحات هناك كائن واحد حيث مستخدمي تسمية سيشير إليها.

وأود أن لا تقلق حول الاستعلامات كثيرا، بفك تخزين الاستفسارات وأن DBMS الخاص بك ربما يكون التخزين المؤقت متفوقة هناك أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top