python - django conf urls




장고는 폼 필드 렌더링 순서를 어떻게 알 수 있습니까? (10)

Django 1.7 양식에서는 추가 연산자를 지원하지 않는 OrderedDict를 사용합니다. 그래서 당신은 처음부터 사전을 재구성해야합니다 ...

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 

내가 장고 양식을 가지고 있다면 :

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

그리고이 폼의 인스턴스에 대해 as_table () 메서드를 호출하면 Django는 필드를 위에서 지정한 것과 같은 순서로 렌더링합니다.

내 질문은 장고 클래스 변수가 정의 된 순서를 어떻게 알 수 있습니까?

(또한 classe의 init 메소드에서 필드를 추가하려는 경우와 같이이 순서를 어떻게 오버라이드합니까?)


Django 1.9는 Form.field_orderForm.order_fields() 합니다.

# example

class SignupForm(forms.Form):

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

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

Field 클래스의 카운터를 사용하십시오. 해당 카운터로 정렬 :

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')]

나는 계속 나아가 내 자신의 질문에 대답했다. 다음 참조 용 답변입니다.

Django에서 form.py__new__ 메소드를 사용하여 클래스 변수를 궁극적으로 클래스에 정의 된 순서대로 self.fields 에로드하는 어두운 마술을 수행합니다. self.fields 는 Django SortedDict 인스턴스입니다 ( datastructures.py 정의되어 있습니다).

그래서 이것을 덮어 쓰려면, 예를 들어 보낸 사람을 먼저 보내고 싶지만 init 메서드에 추가해야한다고 말하면 다음과 같습니다.

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())))

내부 Meta 클래스에서 fields 를 사용하는 것은 Django==1.6.5 대해 저에게 Django==1.6.5 이었습니다 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']

저것과 같이 쉬운.


양식 필드에는 creation_counter라는 creation_counter 순서에 대한 속성이 있습니다. .fields 속성은 사전이므로 사전에 간단히 추가하고 모든 필드의 creation_counter 속성을 변경하여 새로운 순서를 반영하면 충분합니다 (그래도 시도하지 않았습니다).


폼 클래스를 정의 할 때 사용되는 메타 클래스와 관련이 있습니다. 내 생각에는 필드의 내부 목록을 유지하고 목록의 중간에 삽입하면 작동 할 수도 있습니다. 그 코드를 살펴본 지 꽤 오래되었습니다.


필드는 ModelClass._meta.fields에 정의 된 순서대로 나열됩니다. 그러나 Form에서 순서를 변경하려면 keyOrder 함수를 사용하면됩니다. 예 :

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']

fields = '__all__' :

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

또는 exclude 가 사용됩니다.

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

그런 다음 장고 는 모델에 정의 된 대로 필드의 순서를 참조합니다. 이것은 단지 나를 잡았고, 그래서 나는 그것을 언급 할 것이라고 생각했다. 그것은 ModelForm 워드 프로세서 에서 참조됩니다 :

이 두 가지 중 하나를 사용하면 양식에 나타나는 필드의 순서는 필드에 마지막으로 나타나는 ManyToManyField 인스턴스가있는 모델의 순서가됩니다.


[참고 :이 답변은 이제 완전히 구식입니다. 아래의 토론 및 더 최근의 답변을 참조하십시오.

f가 양식 인 경우 해당 필드는 f.fields이며 django.utils.datastructures.SortedDict (항목이 추가 된 순서대로 표시됩니다). 양식 작성 후 f.fields에는 keyOrder 속성이 있습니다.이 속성은 제시해야하는 순서대로 필드 이름을 포함하는 목록입니다. 올바른 주문으로이 항목을 설정할 수 있습니다 (항목을 생략하거나 추가 기능을 추가 할 수 있도록주의해야합니다).

다음은 현재 프로젝트에서 만든 예제입니다.

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




django-forms