জ্যাঙ্গো টেমপ্লেট: একটি পছন্দের ভার্বোজ সংস্করণ


127

আমার একটি মডেল রয়েছে:

from django.db import models

CHOICES = (
    ('s', 'Glorious spam'),
    ('e', 'Fabulous eggs'),
)

class MealOrder(models.Model):
    meal = models.CharField(max_length=8, choices=CHOICES)

আমার একটি ফর্ম রয়েছে:

from django.forms import ModelForm

class MealOrderForm(ModelForm):
    class Meta:
        model = MealOrder

এবং আমি formtools.preview ব্যবহার করতে চাই। ডিফল্ট টেমপ্লেটটি পছন্দের সংক্ষিপ্ত সংস্করণটি ছাপায় ('ফ্যাবুলাস ডিমের পরিবর্তে' ই '), এটি ব্যবহার করার কারণে

{% for field in form %}
<tr>
<th>{{ field.label }}:</th>
<td>{{ field.data }}</td>
</tr>
{% endfor %}.

আমি উল্লিখিত হিসাবে সাধারণ হিসাবে একটি টেমপ্লেট চাই, কিন্তু পরিবর্তে 'চমত্কার ডিম' মুদ্রণ।

[আসল প্রশ্নটি যেখানে আমার সন্দেহ ছিল তাই আমি এটি আমাদের সকলের জন্য সাহসী করেছিলাম :)]

আমি জানি যে কীভাবে নিজের পছন্দ মতো ভার্জোজ ভার্সনটি পেতে হয়:

{{ form.meal.field.choices.1.1 }}

আসল ব্যথা হ'ল আমার নির্বাচিত পছন্দটি পাওয়া দরকার, এবং আমার মনে আসার একমাত্র উপায় হ'ল পছন্দগুলির মাধ্যমে পুনরাবৃত্তি করা এবং চেক করা {% ifequals currentChoice.0 choiceField.data %}, যা এমনকি খারাপও নয়।

সহজেই করা যায়? নাকি এর জন্য কিছু টেমপ্লেট-ট্যাগ প্রোগ্রামিং দরকার? এটি জ্যাঙ্গোতে পাওয়া উচিত নয়?

উত্তর:


258

জাজানো টেমপ্লেটগুলিতে আপনি " get_FOO_display()" পদ্ধতিটি ব্যবহার করতে পারেন , এটি ক্ষেত্রের জন্য পঠনযোগ্য উপন্যাসটি ফিরিয়ে দেবে, যেখানে ক্ষেত্রটির নাম 'এফইউ'।

দ্রষ্টব্য: যদি মানক FormPreviewটেম্পলেটগুলি এটি ব্যবহার না করে তবে আপনি সর্বদা সেই ফর্মটির জন্য নিজের টেম্পলেট সরবরাহ করতে পারেন , যাতে এর মতো কিছু থাকে {{ form.get_meal_display }}


1
হ্যা আমি জানি. এটি সাধারণ (সর্বজনীন) নয়, যদিও - আপনি যদি কোনও মডেল অবজেক্টের get_FOO_display পদ্ধতিতে কোনও টেম্পলেটটিতে পুনরাবৃত্তি করার উপায় জানেন না তবে :) আমি জেনেরিক অ-টেম্পলেটগুলি লেখার জন্য কিছুটা অলস;) তদ্ব্যতীত ডকস বলে এটি একটি মডেল উদাহরণের পদ্ধতি। অতএব এটি কোনও বিদ্যমান অবজেক্টের সাথে আবদ্ধ একটি মডেল ফর্ম হতে হবে যা কেস নয় এবং সাধারণও নয়।
আরতুর গাজোয়ি

2
মনে রাখবেন যে এই ব্যবহারটি দর্শনগুলির মধ্যে সীমাবদ্ধ নয়, get_FOO_display () নিজেই মডেল অবজেক্টের একটি পদ্ধতি যাতে আপনি এটি মডেল কোডেও ব্যবহার করতে পারেন! উদাহরণস্বরূপ, __unicode __ () এ এটি খুব সুবিধাজনক
বোগাতিয়ার

51

আপনার সমস্যার সর্বোত্তম সমাধান হ'ল সহায়ক ফাংশন ব্যবহার করা। পছন্দ পরিবর্তনশীল সঞ্চিত হয় বাছাই এবং মডেল ক্ষেত্র নির্বাচিত পছন্দ সংরক্ষণকারী 'হল পছন্দ ' তারপর আপনি সরাসরি ব্যবহার করতে পারেন

 {{ x.get_choices_display }}

আপনার টেম্পলেট মধ্যে। এখানে, x হল মডেল উদাহরণ। আশা করি এটা সাহায্য করবে.


3
ইতিমধ্যে একটি কার্যকর উত্তর ইতিমধ্যে 2 বছর পরে আপনি কেন এইরকম উত্তর দেবেন? আর কে ভোট দেবে? ঠিক 2 বছর পরে
@roberto

15
@ মার্ক0978 এই উত্তরটিকে সমর্থন করার কারণ কারণ (আমার পক্ষে) তখন "শীর্ষে ভোট দেওয়া" উত্তরটি অনুসরণ করা আরও পরিষ্কার ছিল। YMMV।
নীড় লেভি

49

আমার উত্তর যদি উপরে উল্লিখিত কোনওর সাথে অপ্রয়োজনীয় হয় তবে এটি প্রদর্শিত হয় এটি এখনও সরবরাহ করা হয়নি এবং এটি মোটামুটি পরিষ্কার বলে মনে হচ্ছে। আমি কীভাবে এটি সমাধান করেছি তা এখানে:

from django.db import models

class Scoop(models.Model):
    FLAVOR_CHOICES = [
        ('c', 'Chocolate'),
        ('v', 'Vanilla'),
    ]

    flavor = models.CharField(choices=FLAVOR_CHOICES)

    def flavor_verbose(self):
        return dict(Scoop.FLAVOR_CHOCIES)[self.flavor]

আমার দৃশ্য টেমপ্লেট (নোট: থেকে একটি ছাঁকি পাসের না Scoop.values ()), এবং টেমপ্লেট রয়েছে:

{{ scoop.flavor_verbose }}

10

নোহের জবাবের উপর ঝাঁকুনি দেওয়া, এখানে কোনও পছন্দ ছাড়াই ক্ষেত্রগুলির প্রতিরোধ ক্ষমতা রয়েছে:

#annoyances/templatetags/data_verbose.py
from django import template

register = template.Library()

@register.filter
def data_verbose(boundField):
    """
    Returns field's data or it's verbose version 
    for a field with choices defined.

    Usage::

        {% load data_verbose %}
        {{form.some_field|data_verbose}}
    """
    data = boundField.data
    field = boundField.field
    return hasattr(field, 'choices') and dict(field.choices).get(data,'') or data

আমি নিশ্চিত না যে এই জাতীয় উদ্দেশ্যে ফিল্টার ব্যবহার করা ঠিক আছে। কারওরও যদি এর থেকে আরও ভাল সমাধান থাকে তবে আমি এটি দেখে খুশি হব :) আপনাকে ধন্যবাদ নোহ!


আপনার পথটি উল্লেখ করার জন্য +1 # বিরক্তি / টেমপ্লেট ট্যাগগুলি ... ... এলএল ... আমি get_FOO_display () ব্যবহার করি যা ফর্ম ডক্সের নীচে উল্লিখিত হয়েছে।
fmalina

পছন্দগুলিতে তাত্ক্ষণিক ব্যবহারের সাথে দুর্দান্ত ধারণা!
ওডেন

7

নোহের দ্বারা ফিল্টার সমাধানটি ডেটা এবং ফিল্ডের ধরণের ক্ষেত্রে আরও সার্বজনীন হতে আমরা প্রসারিত করতে পারি :

<table>
{% for item in query %}
    <tr>
        {% for field in fields %}
            <td>{{item|human_readable:field}}</td>
        {% endfor %}
    </tr>
{% endfor %}
</table>

কোডটি এখানে:

#app_name/templatetags/custom_tags.py
def human_readable(value, arg):
    if hasattr(value, 'get_' + str(arg) + '_display'):
        return getattr(value, 'get_%s_display' % arg)()
    elif hasattr(value, str(arg)):
        if callable(getattr(value, str(arg))):
            return getattr(value, arg)()
        else:
            return getattr(value, arg)
   else:
       try:
           return value[arg]
       except KeyError:
           return settings.TEMPLATE_STRING_IF_INVALID
register.filter('human_readable', human_readable)

বেশ সর্বজনীন বলে মনে হচ্ছে :) নিশ্চিত করে বলতে পারছি না, কারণ আমি সেই সময় থেকে খুব বেশি পাইথন বা জ্যাঙ্গো করিনি। যদিও এটি অত্যন্ত দুঃখজনক, এটি এখনও তৃতীয় পক্ষের (জ্যাঙ্গোতে অন্তর্ভুক্ত নয়) ফিল্টারের প্রয়োজন (অন্যথায় আপনি আমাদের বলতে চান, ইভান, আপনি কি না ?;)) ...
আর্তুর গাজোভি

@ আরতুরগাজোয়ে হ্যাঁ, আজকের মতো জ্যাঙ্গোতে এ জাতীয় কোনও ডিফল্ট বৈশিষ্ট্য নেই। আমি এটি প্রস্তাব করেছি, কে জানে, সম্ভবত এটি অনুমোদিত হবে
ইভান খারলামভ

পারফেক্ট! একটি যাদুমন্ত্র মত কাজ করে! কাস্টম টেমপ্লেট ফিল্টারস রক্স! ধন্যবাদ! :-)
সিডেরোম

5

আমি মনে করি না যে এটি করার জন্য কোনও অন্তর্নির্মিত উপায় আছে। একটি ফিল্টার কৌশলটি করতে পারে, যদিও:

@register.filter(name='display')
def display_value(bf):
    """Returns the display value of a BoundField"""
    return dict(bf.field.choices).get(bf.data, '')

তারপরে আপনি এটি করতে পারেন:

{% for field in form %}
    <tr>
        <th>{{ field.label }}:</th>
        <td>{{ field.data|display }}</td>
    </tr>
{% endfor %}

3

আপনার মডেলগুলিতে যুক্ত করুন pyএকটি সাধারণ ফাংশন:

def get_display(key, list):
    d = dict(list)
    if key in d:
        return d[key]
    return None

এখন, আপনি পছন্দ মত ক্ষেত্রের ভার্বোজ মান পেতে পারেন:

class MealOrder(models.Model):
    meal = models.CharField(max_length=8, choices=CHOICES)

    def meal_verbose(self):
        return get_display(self.meal, CHOICES)    

আপডেট: আমি নিশ্চিত নই যে সমাধানটি "পাইথোনিক" এবং "জ্যাঙ্গো-ওয়ে" যথেষ্ট বা না, তবে এটি কার্যকর। :)


0

আপনার কাছে Model.get_FOO_display () রয়েছে যেখানে FOO এমন ক্ষেত্রের নাম যেখানে পছন্দ রয়েছে।

আপনার টেমপ্লেটে এটি করুন:

{{ scoop.get_flavor_display }}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.