Как делает Django Know Порядок Представить Поля Формы?

84
задан Zulu 6 February 2018 в 19:40
поделиться

6 ответов

Я шел вперед и ответил на свой собственный вопрос. Вот ответ для дальнейшего использования:

В 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())))
38
ответ дан Greg 24 November 2019 в 08:28
поделиться

Это имеет отношение к метаклассу, который используется в определении класса формы. Я думаю, что это сохраняет внутренний список полей и если Вы вставляете в середину списка, это могло бы работать. Это было некоторое время, так как я посмотрел на тот код.

0
ответ дан Sam Corder 24 November 2019 в 08:28
поделиться

Поля формы имеют атрибут для порядка создания, названного creation_counter. .fields атрибут является словарем, так простое добавление к словарю и изменение creation_counter атрибуты во всех полях, чтобы отразить, что новое упорядочивание должно быть достаточным (никогда не пробовал это, хотя).

5
ответ дан zgoda 24 November 2019 в 08:28
поделиться

Используйте счетчик в классе 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')]

5
ответ дан 24 November 2019 в 08:28
поделиться

[NOTE: this answer is now pretty completely outdated - please see the discussion below it, and more recent answers].

If f is a form, its fields are f.fields, which is a django.utils.datastructures.SortedDict (it presents the items in the order they are added). After form construction f.fields has a keyOrder attribute, which is a list containing the field names in the order they should be presented. You can set this to the correct ordering (though you need to exercise care to ensure you don't omit items or add extras).

Here's an example I just created in my current project:

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
89
ответ дан 24 November 2019 в 08:28
поделиться

На будущее: со времен newforms все немного изменилось. Это один из способов переупорядочивания полей из базовых классов форм, над которым вы не имеете контроля:

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

Также, есть немного документации о SortedDict, который base_fields использует здесь: http://code.djangoproject.com/wiki/SortedDict

3
ответ дан 24 November 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: