首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >澄清Django选择力学

澄清Django选择力学
EN

Stack Overflow用户
提问于 2015-10-22 04:52:40
回答 1查看 40关注 0票数 0

假设我想在一栋楼里预订,而选择是根据所选的楼层而改变的。

在我的forms.py

代码语言:javascript
复制
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

代码语言:javascript
复制
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个参数意味着什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-22 07:45:33

这更像是Python问题,而不是Django问题,因为它比任何其他问题更关注对象继承和初始化。

以下是简短的版本:

__init__是在初始化实例时调用的方法。它实际上不是构造函数(称为__new__),但是当您执行以下操作时

代码语言:javascript
复制
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处理任意参数的方法。

例如,如果你有这样的

代码语言:javascript
复制
def foo(param1):
    pass

如果你调用foo(1, 2, a=5),你会得到一个关于参数数量的错误。但是,如果您像这样定义了您的方法:

代码语言:javascript
复制
def foo(param1, *args, **kwargs):
    pass

您调用相同的foo(1, 2, a=5),args现在将是一个列表[1],kwargs将是一个字典{'a': 5},很明显您不会收到任何错误。

当您不想关心您正在重写的父方法所拥有的所有参数时,*args**kwargs尤其有用--就像这里的例子一样,forms.Form.__init__有很多参数--您没有接触到这些参数。您只需在它们前面添加参数,*args**kwargs就会在继承链中接受任何其他潜在的参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33273641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档