জঙ্গো কীভাবে ফর্ম ক্ষেত্রগুলি রেন্ডার করার আদেশ জানে?


91

যদি আমার কাছে জ্যাঙ্গো ফর্ম থাকে তবে:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()

এবং আমি এই ফর্মের উদাহরণের as_table () পদ্ধতিটি কল করি, জ্যাঙ্গো ক্ষেত্রগুলিকে উপরে উল্লিখিত একই ক্রম হিসাবে রেন্ডার করবে।

আমার প্রশ্ন হ'ল জাজাগো কীভাবে শ্রেণীর ভেরিয়েবলগুলি সংজ্ঞায়িত করার ক্রমটি জানতে পারে?

(এছাড়াও আমি উদাহরণস্বরূপ এই আদেশ অগ্রাহ্য না, যখন আমি classe থেকে একটি ক্ষেত্র যোগ করতে চান Init পদ্ধতি?)

উত্তর:


89

[দ্রষ্টব্য: এই উত্তরটি এখন পুরোপুরি পুরানো - দয়া করে নীচের আলোচনাটি এবং আরও সাম্প্রতিক উত্তরগুলি দেখুন]।

যদি fকোনও ফর্ম হয় তবে এর ক্ষেত্রগুলি f.fieldsহ'ল django.utils.datastructures.SortedDict এটি (এটি আইটেমগুলি যুক্ত করার ক্রমে উপস্থাপন করে)। ফর্ম নির্মাণের পরে এফ.ফিল্ডগুলির একটি কী-অর্ডার বৈশিষ্ট্য রয়েছে, যা ক্ষেত্রের নামগুলি যাতে উপস্থাপন করা উচিত সেগুলি সহ একটি তালিকা। আপনি এটিকে সঠিক ক্রমটিতে সেট করতে পারেন (যদিও আপনার আইটেম বাদ দেওয়া বা অতিরিক্ত না যুক্ত তা নিশ্চিত করার জন্য আপনার যত্ন নেওয়া প্রয়োজন)।

আমি এখানে আমার বর্তমান প্রকল্পে একটি উদাহরণ তৈরি করেছি:

class PrivEdit(ModelForm):
    def __init__(self, *args, **kw):
        super(ModelForm, self).__init__(*args, **kw)
        self.fields.keyOrder = [
            'super_user',
            'all_districts',
            'multi_district',
            'all_schools',
            'manage_users',
            'direct_login',
            'student_detail',
            'license']
    class Meta:
        model = Privilege

20
কিছু সময়ের জন্য, ক্ষেত্রগুলি একটি মডেলফর্মের 'ক্ষেত্রগুলি' বৈশিষ্ট্য অনুসারে অর্ডার করা হবে। ডকস.ডজ্যাঙ্গোপ্রজেক্ট / এএন / ১.৩ / টোপিক্স / সফটওয়্যার / মডেলফর্মগুলি .......... থেকে : ক্ষেত্রের নামগুলি সেই তালিকায় নির্দিষ্ট করা হয় সেই ফর্মটি যখন তাদের রেন্ডার করে তখন তাকে সম্মান করা হয়। এটি কেবল মডেলফর্মগুলির জন্যই কাজ করে - আপনার পদ্ধতির নিয়মিত ফর্মগুলির জন্য বিশেষত ফর্ম সাবক্লাসগুলি অতিরিক্ত ক্ষেত্র যুক্ত করার জন্য এখনও যথেষ্ট কার্যকর।
ক্রিস লোলর

4
এটি কাজ করে যখন আপনি কিছু ক্ষেত্রকে ওভাররাইড করে অন্যদের নয় doing +1
নাথন কেলার

"এটি" ক্রিস লোলারের পরামর্শ হচ্ছে? এই উত্তরটি যথেষ্ট পুরনো যে সম্ভবত এটি আর বর্তমান নয় (তবে সম্ভবত এটি 1.2 এর জন্য ভাল ছিল)। অবিশ্বাস্য তথ্য পতাকাঙ্কিত হয় তা নিশ্চিত করা গুরুত্বপূর্ণ, অন্যথায় নতুনরা কীসের উপর নির্ভর করবেন তা জানেন না। আপনার ইনপুট জন্য ধন্যবাদ।
হোল্ডেনওয়েব

72

জাজানো ১.৯-এ নতুন ফর্ম.ফিল্ডফর্ডার এবং ফর্ম.অর্ডার_ফিল্ডস ()

# forms.Form example
class SignupForm(forms.Form):

    password = ...
    email = ...
    username = ...

    field_order = ['username', 'email', 'password']


# forms.ModelForm example
class UserAccount(forms.ModelForm):

    custom_field = models.CharField(max_length=254)

    def Meta:
        model = User
        fields = ('username', 'email')

    field_order = ['username', 'custom_field', 'password']

4
এই উত্তর আমি খুঁজছি!
শিববধু

4
১.৯ অনুসারে এটি নতুন উত্তরদাতাদের উচিত উত্তর হওয়া উচিত, স্পষ্টতই এখনও 1.10 তে কাজ করে
ব্রায়ান এইচ।

4
দ্রষ্টব্য: এটি "ফিল্ডসর্ডার" নয় "ফিল্ড_আর্ডার" (কোনও 'গুলি' নয়)
ডেভি

4
এমনকি আপনি যে ফর্ম ক্ষেত্রগুলি অর্ডার করতে চান তার কেবলমাত্র একটি উপসেট নির্দিষ্ট করতে পারেন
ড্যানলেব 2

40

আমি এগিয়ে গিয়ে নিজের প্রশ্নের উত্তর দিয়েছি। ভবিষ্যতের রেফারেন্সের জন্য এখানে উত্তর:

জাজানোতে ক্লাসে সংজ্ঞায়িত ক্রমে আপনার ক্লাসের ভেরিয়েবলগুলি শেষ পর্যন্ত লোড form.pyকরার __new__পদ্ধতিটি ব্যবহার করে কিছু গা dark ় যাদু করে self.fieldsself.fieldsএটি একটি জ্যাঙ্গো SortedDictউদাহরণ (সংজ্ঞায়িত datastructures.py)।

সুতরাং এটিকে ওভাররাইড করার জন্য, আমার উদাহরণে বলুন আপনি প্রেরককে প্রথমে আসতে চেয়েছিলেন তবে এটির একটি ডিআইডি পদ্ধতিতে যুক্ত করার দরকার ছিল , আপনি যা করবেন:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    def __init__(self,*args,**kwargs):
        forms.Form.__init__(self,*args,**kwargs)
        #first argument, index is the position of the field you want it to come before
        self.fields.insert(0,'sender',forms.EmailField(initial=str(time.time())))

12
আপনি শীর্ষে 'প্রেরক' ক্ষেত্রটিকে সাধারণ হিসাবে সংজ্ঞায়িত করতে পারেন এবং তারপরে আপনার self.fields.insert( 0, 'sender', self.fields['sender'] )
sertোকানো

4
এটি আর জ্যাঙ্গো ১.7 এ আর কাজ করে না কারণ ফর্ম ক্ষেত্রগুলি অর্ডারডিক্ট ব্যবহার করে যা সংযোজন সমর্থন করে না। নীচে আমার আপডেট হওয়া উত্তরটি দেখুন (মন্তব্যের জন্য খুব দীর্ঘ) ...
পল কেনজোরা

11

ক্ষেত্রগুলি ModelClass._meta.fields এ সংজ্ঞায়িত ক্রমে সেগুলি তালিকাভুক্ত করা হয়েছে। তবে আপনি যদি ফর্মটিতে অর্ডার পরিবর্তন করতে চান তবে আপনি কী-অর্ডার ফাংশনটি ব্যবহার করে করতে পারেন। উদাহরণ স্বরূপ :

class ContestForm(ModelForm):
  class Meta:
    model = Contest
    exclude=('create_date', 'company')

  def __init__(self, *args, **kwargs):
    super(ContestForm, self).__init__(*args, **kwargs)
    self.fields.keyOrder = [
        'name',
        'description',
        'image',
        'video_link',
        'category']

6

জ্যাঙ্গো> = 1.7 এর সাথে আপনার ContactForm.base_fieldsনীচের মত পরিবর্তন করতে হবে :

from collections import OrderedDict

...

class ContactForm(forms.Form):
    ...

ContactForm.base_fields = OrderedDict(
    (k, ContactForm.base_fields[k])
    for k in ['your', 'field', 'in', 'order']
)

এই কৌশলটি জ্যাঙ্গো অ্যাডমিনে ব্যবহৃত হয় PasswordChangeForm: গিথুব-এর উত্স


4
মজার বিষয় হল, সাবক্লাসিং কেন ক্ষেত্রগুলির ক্রম PasswordChangeFormপরিবর্তন করেছে তা নির্ধারণের চেষ্টা করার সময় আমি ক্ষেত্রগুলির ক্রমগুলি সন্ধান করার চেষ্টা করেছি , সুতরাং আপনার উদাহরণটি আমার পক্ষে খুব দরকারী। দেখে মনে হচ্ছে এটি base_fieldsসাবক্লাসে পৌঁছে না বলেই । সমাধানটি PasswordChangeFormSubclass.base_fields = PasswordChangeForm.base_fields"পাসওয়ার্ড
চেঞ্জফর্মসব্ল্যাক্লাস

@orblivion: আদেশযুক্ত ContactForm.base_fields[k]ডিক তৈরির সময় ব্যবহার করুন । একটি টাইপ এন এর উত্তর আছে, আমি সম্পাদনা করব
ব্লুফাস্ট

5

ফর্ম ক্ষেত্রগুলিতে বলা হয় ক্রম ক্রমের জন্য একটি বৈশিষ্ট্য creation_counter.fieldsঅ্যাট্রিবিউট একটি অভিধান, তাই অভিধানে যোগ করা এবং creation_counterনতুন ক্রম প্রতিফলিত করতে সমস্ত ক্ষেত্রে গুণাবলী পরিবর্তন করা যথেষ্ট হওয়া উচিত (যদিও এটি কখনও চেষ্টা করা হয়নি)।


5

ফিল্ড ক্লাসে একটি কাউন্টার ব্যবহার করুন। এই কাউন্টার অনুসারে বাছাই করুন:

import operator
import itertools

class Field(object):
    _counter = itertools.count()
    def __init__(self):
        self.count = Field._counter.next()
        self.name = ''
    def __repr__(self):
        return "Field(%r)" % self.name

class MyForm(object):
    b = Field()
    a = Field()
    c = Field()

    def __init__(self):
        self.fields = []
        for field_name in dir(self):
            field = getattr(self, field_name)
            if isinstance(field, Field):
                field.name = field_name
                self.fields.append(field)
        self.fields.sort(key=operator.attrgetter('count'))

m = MyForm()
print m.fields # in defined order

আউটপুট:

[Field('b'), Field('a'), Field('c')]


4

জ্যাঙ্গো হিসাবে ১.7 ফর্মগুলি অর্ডারডিক্ট ব্যবহার করে যা অ্যাপেন্ড অপারেটরকে সমর্থন করে না। সুতরাং আপনাকে স্ক্র্যাচ থেকে অভিধানটি পুনর্নির্মাণ করতে হবে ...

class ChecklistForm(forms.ModelForm):

  class Meta:
    model = Checklist
    fields = ['name', 'email', 'website']

  def __init__(self, guide, *args, **kwargs):
    self.guide = guide
    super(ChecklistForm, self).__init__(*args, **kwargs)

    new_fields = OrderedDict()
    for tier, tasks in guide.tiers().items():
      questions = [(t['task'], t['question']) for t in tasks if 'question' in t]
      new_fields[tier.lower()] = forms.MultipleChoiceField(
        label=tier,
        widget=forms.CheckboxSelectMultiple(),
        choices=questions,
        help_text='desired set of site features'
      )

    new_fields['name'] = self.fields['name']
    new_fields['email'] = self.fields['email']
    new_fields['website'] = self.fields['website']
    self.fields = new_fields 

পাইথন ৩.২ যেহেতু আপনি অর্ডারডটিক্ট.মোভ_টো_েন্ড () আইটেমগুলি সংযোজন বা সংযোজন করতে ব্যবহার করতে পারেন।
বিপি পার্কার

3

ভবিষ্যতের রেফারেন্সের জন্য: নতুন সংস্করণ থেকে জিনিসগুলি কিছুটা পরিবর্তন হয়েছে। বেস ফর্মক্ল্যাসগুলি থেকে ক্ষেত্রগুলিকে পুনরায় সাজানোর এক উপায় এটিতে আপনার কোনও নিয়ন্ত্রণ নেই:

def move_field_before(form, field, before_field):
    content = form.base_fields[field]
    del(form.base_fields[field])
    insert_at = list(form.base_fields).index(before_field)
    form.base_fields.insert(insert_at, field, content)
    return form

এছাড়াও, base_fieldsএখানে ব্যবহৃত সোর্টডিক্ট সম্পর্কে কিছুটা ডকুমেন্টেশন রয়েছে : http://code.djangoproject.com/wiki/SortDict


আমার ক্লাসে 'ক্ষেত্রগুলি' ব্যবহার করে মেটা আমার জন্য কাজ করেছিল (একটি মডেলফর্ম সহ) যতক্ষণ না আমার মাইফর্মসেট.ফর্ম.বেস_ফিল্ড ব্যবহার করে কোনও বিদেশী কী ক্ষেত্রের জন্য প্রাথমিক মান নির্ধারণ করার কারণ ছিল, যেখানে 'ক্ষেত্রগুলিতে' ক্রমটি ছিল না আর সম্মানিত। আমার সমাধানটি আসলে অন্তর্নিহিত মডেলের ক্ষেত্রগুলিকে পুনরায় অর্ডার করার জন্য ছিল।
পল জে

2

যদি হয় fields = '__all__':

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = '__all__'

বা excludeব্যবহৃত হয়:

class PartialAuthorForm(ModelForm):
    class Meta:
        model = Author
        exclude = ['title']

তারপরে জাজানো মডেলের সংজ্ঞা অনুসারে ক্ষেত্রগুলির ক্রম উল্লেখ করে । এটি কেবল আমাকে ধরা দিয়েছে, তাই আমি ভেবেছিলাম আমি এটি উল্লেখ করব। এটি মডেলফর্ম ডক্সে উল্লেখ করা হয়েছে :

এর মধ্যে দুটি যদি ব্যবহার করা হয়, ফর্মগুলিতে ক্ষেত্রগুলি যে ক্রম হিসাবে উপস্থিত হবে তা হ'ল মডেলগুলিতে ক্ষেত্রগুলি সংজ্ঞায়িত করা হবে, ম্যান্টিটোম্যানিফিল্ডের উদাহরণগুলি সর্বশেষে উপস্থিত হবে।


2

জঙ্গো ১.৯ ফর্মগুলিতে ক্ষেত্রগুলি অর্ডার করার সবচেয়ে সহজ উপায় হ'লfield_order আপনার ফর্ম.ফিল্ডফর্ডারটিতে ব্যবহার করা

এখানে একটি ছোট উদাহরণ

class ContactForm(forms.Form):
     subject = forms.CharField(max_length=100)
     message = forms.CharField()
     sender = forms.EmailField()
     field_order = ['sender','message','subject']

এটি field_orderডিকটিতে আপনি যে ক্রমটি নির্দিষ্ট করেছেন তাতে সবকিছু প্রদর্শিত হবে ।


1

ব্যবহার fieldsভেতরের মধ্যে Metaবর্গ কি আমার জন্য কাজ হল Django==1.6.5:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Example form declaration with custom field order.
"""

from django import forms

from app.models import AppModel


class ExampleModelForm(forms.ModelForm):
    """
    An example model form for ``AppModel``.
    """
    field1 = forms.CharField()
    field2 = forms.CharField()

    class Meta:
        model = AppModel
        fields = ['field2', 'field1']

এর মত সহজ.


4
দেখে মনে হচ্ছে এই পদ্ধতিটি কেবল মডেলফর্মের জন্য বৈধ, সাধারণ ফর্মটি django.formsকাজ করে না
Pengfei.X

1

আমি ক্ষেত্রগুলি সরানোর জন্য এটি ব্যবহার করেছি:

def move_field_before(frm, field_name, before_name):
    fld = frm.fields.pop(field_name)
    pos = frm.fields.keys().index(before_name)
    frm.fields.insert(pos, field_name, fld)

এটি 1.5 এ কাজ করে এবং আমি যুক্তিযুক্ত নিশ্চিত যে এটি এখনও আরও সাম্প্রতিক সংস্করণগুলিতে কাজ করে।


0

এটি ফর্ম শ্রেণির সংজ্ঞায়িত করতে ব্যবহৃত মেটা বর্গের সাথে সম্পর্কিত। আমি মনে করি এটি ক্ষেত্রগুলির একটি অভ্যন্তরীণ তালিকা রাখে এবং আপনি যদি তালিকার মাঝখানে itোকান তবে এটি কার্যকর হতে পারে। আমি সেই কোডটির দিকে চেয়ে কিছুক্ষণ হয়েছি।

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