2015-04-17 4 views
1

У меня есть список питонапитон глобальное имя не определено

readonly = ['name', 'description']

, что я хочу использовать в нескольких методов. Однако я получаю глобальную переменную не определена ошибка

class EditForm(ModelForm): 
    # When editing form we want to disable multiple fields 
    # Admin users can edit existing items via admin interface 
    readonly = ['name', 'description'] 

    def __init__(self, *args, **kwargs): 
     super(EditForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     for ro_field in readonly: 
      if instance and instance.pk: 
       self.fields[ro_field].widget.attrs['readonly'] = True 

Как сохранить список местных и иметь возможность использовать его в __init__ функции и последующих методов, не повторяя настройки списка в каждой функции

ответ

1

Когда ты напишите код, как вы,

class EditForm(ModelForm): 
    # When editing form we want to disable multiple fields 
    # Admin users can edit existing items via admin interface 
    readonly = ['name', 'description'] 

    def __init__(self, *args, **kwargs): 
     super(EditForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     for ro_field in readonly: 
      if instance and instance.pk: 
       self.fields[ro_field].widget.attrs['readonly'] = True 

Вы создаете нечто, что вы бы назвали статической переменной. Для Асесса, вы должны использовать последующий синтаксис

ClassName.variable 

или self.variable

Таким образом, чтобы получить доступ к нему, просто сделать:

class EditForm(ModelForm): 
    # When editing form we want to disable multiple fields 
    # Admin users can edit existing items via admin interface 
    readonly = ['name', 'description'] 

    def __init__(self, *args, **kwargs): 
     super(EditForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     for ro_field in EditForm.readonly: 
      if instance and instance.pk: 
       self.fields[ro_field].widget.attrs['readonly'] = True 

Разницы между объявляя

readonly = ['name', 'description'] 

И

self.readonly = ['name', 'description'] 

Является ли это то, что второй случай означает, что атрибут принадлежит экземпляру, который вы создали, поэтому каждый объект будет иметь свой собственный список readonly, и если вы измените его или что-то еще, вам придется изменить его для каждого объекта.

В первом случае атрибут принадлежит классу, поэтому он равен во всех объектах.

+1

Вы также можете использовать 'self.attr' для доступа атрибутов класса внутри методов экземпляра (хотя, если вы * присвоить to * 'self.attr', вы создаете атрибут экземпляра, который тени атрибута класса). – jonrsharpe

1

readonly - вот атрибут вашего класса EditForm. Вы можете получить доступ к нему либо через класс (EditForm.readonly) или - лучше - через сам, например:

class EditForm(ModelForm): 
    # When editing form we want to disable multiple fields 
    # Admin users can edit existing items via admin interface 
    readonly = ['name', 'description'] 

    def __init__(self, *args, **kwargs): 
     super(EditForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     if instance and instance.pk: 
      for ro_field in self.readonly: 
       self.fields[ro_field].widget.attrs['readonly'] = True 

Это лучше получить к нему доступ через экземпляр, как это позволяет избежать жесткого кодирования имя класса в метод, и будет лучше поддержка наследование (если вы подклассом EditForm и хотите переопределить readonly в вашем подклассе).

Также я поставил тест if instance and instance.pk перед циклом - не нужно перепроверять, если для каждой итерации;)

Смежные вопросы