假设我想在一栋楼里预订,而选择是根据所选的楼层而改变的。
在我的forms.py中
class BookingForm(forms.Form):
name = forms.CharField()
room = forms.ChoiceField()
def __init__(self, room_choices, *args, **kwargs):
super(BookingForm, self).__init__(*args, **kwargs)
self.fields['room'].choices = room_choices在views.py
def book_room(request):
choices = Choices.all().list_values('rooms').filter(floor=floor)
room_choices = []
for c in choices:
room_choices.append((c, c), )
booking_form = BookingForm(room_choices)我的问题是,这其中的机制是什么?特别是,def __init__和方法的4个参数意味着什么?
发布于 2015-10-22 07:45:33
这更像是Python问题,而不是Django问题,因为它比任何其他问题更关注对象继承和初始化。
以下是简短的版本:
__init__是在初始化实例时调用的方法。它实际上不是构造函数(称为__new__),但是当您执行以下操作时
booking_form = BookingForm(room_choices) 将在构造函数之后调用__init__。
通过调用super(BookingForm, self).__init__(*args, **kwargs),您可以允许初始化在继承链上冒泡。在这种情况下,您允许forms.Form完成它需要完成的所有初始化,包括定义表单和设置您定义的字段。
在Form实例上定义字段之后,将覆盖room字段上的选项。如果您试图切换这两行,以便在父初始化之前进行覆盖,那么您将得到一个KeyError,因为在这一点上不存在self.fields。
至于帕勒姆:
self是对当前实例的引用,必须传递给每个实例方法。这就是Python处理实例方法的方式(它相当于this在Java中的作用)room_choices是你的副词*args和**kwargs是Python处理任意参数的方法。例如,如果你有这样的
def foo(param1):
pass如果你调用foo(1, 2, a=5),你会得到一个关于参数数量的错误。但是,如果您像这样定义了您的方法:
def foo(param1, *args, **kwargs):
pass您调用相同的foo(1, 2, a=5),args现在将是一个列表[1],kwargs将是一个字典{'a': 5},很明显您不会收到任何错误。
当您不想关心您正在重写的父方法所拥有的所有参数时,*args和**kwargs尤其有用--就像这里的例子一样,forms.Form.__init__有很多参数--您没有接触到这些参数。您只需在它们前面添加参数,*args和**kwargs就会在继承链中接受任何其他潜在的参数。
https://stackoverflow.com/questions/33273641
复制相似问题