Эта статья помогла мне многочисленные времена.
суть его включает переопределение ModelForm __init__
метод, затем называя суперкласс __init__
метод, затем корректируя поля индивидуально.
class PollForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PollForm, self).__init__(*args, **kwargs)
self.fields['question'].widget = forms.Textarea()
class Meta:
model = Poll
Этот метод может казаться более сложным, чем Vasil, но он предлагает дополнительную выгоду способности точно переопределить любой атрибут на поле, не сбрасывая никакие другие атрибуты путем переобъявления этого.
ОБНОВЛЕНИЕ: Предложенный подход мог быть обобщен для изменения всех полей даты, не вводя каждое имя строго:
from django.forms import fields as formfields
from django.contrib.admin import widgets
class PollForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PollForm, self).__init__(*args, **kwargs)
for field_name in self.fields:
field = self.fields[field_name]
if isinstance(field, formfields.DateField):
field.widget = widgets.AdminDateWidget()
class Meta:
model = Poll
Это работало на меня на python3
и django 1.11
Обратите внимание, что в других языках, чувствительных к пробелам, таких как Haskell, обработка макета действительно выполняется в лексере. Фактически GHC реализует обработку макета в Alex. Вот источник:
https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x
В вашем вопросе есть несколько серьезных ошибок, которые сбивают вас с пути, как указывает jrockway . "Я могу' позволяя вам распределять состояние через ваш лексер. Затем посмотрите, как состояние используется в реализации макета GHC для реализации отступа / удаления правил макета. (Найдите «- Обработка макета» в лексере GHC, чтобы увидеть, как состояние перемещается и выталкивается).
позволяя вам распределять состояние через ваш лексер. Затем посмотрите, как состояние используется в реализации макета GHC для реализации отступа / удаления правил макета. (Найдите «- Обработка макета» в лексере GHC, чтобы увидеть, как состояние перемещается и выталкивается).I can't store any global data anywhere with Haskell
This is not true; in most cases something like the State monad is sufficient, but there is also the ST monad.
You don't need global state for this task, however. Writing a parser consists of two parts; lexical analysis and syntax analysis. The lexical analysis just turns a stream of characters into a stream of meaningful tokens. The syntax analysis turns tokens into an AST; this is where you should deal with indentation.
As you are interpreting the indentation, you will call a handler function as the indentation level changes -- when it increases (nesting), you call your handler function (perhaps with one arg incremented, if you want to track the indentation level); when the level decreases, you simply return the relevant AST portion from the function.
(As an aside, using a global variable for this is something that would not occur to me in an imperative language either -- if anything, it's an instance variable. The State monad is very similar conceptually to this.)
Finally, I think the phrase "I can't put all my lexing rules inside any monad" indicates some sort of misunderstanding of monads. If I needed to parse and keep global state, my code would look like:
data AST = ...
type Step = State Int AST
parseFunction :: Stream -> Step
parseFunction s = do
level <- get
...
if anotherFunction then put (level + 1) >> parseFunction ...
else parseWhatever
...
return node
parse :: Stream -> Step
parse s = do
if looksLikeFunction then parseFunction ...
main = runState parse 0 -- initial nesting of 0
Instead of combining function applications with (.)
or ($)
, you combine them with (>>=)
or (>>)
. Other than that, the algorithm is the same. (There is no "monad" to be "inside".)
Finally, you might like applicative functors:
eval :: Environment -> Node -> Evaluated
eval e (Constant x) = Evaluated x
eval e (Variable x) = Evaluated (lookup e x)
eval e (Function f x y) = (f <$> (`eval` x) <*> (`eval` y)) e
(or
eval e (Function f x y) = ((`eval` f) <*> (`eval` x) <*> (`eval` y)) e
if you have something like "funcall"... but I digress.)
There is plenty of literature on parsing with applicative functors, monads, and arrows; all of which have the potential to solve your problem. Read up on those and see what you get.