【发布时间】:2014-10-28 17:17:59
【问题描述】:
假设我有以下模型...
class Person(models.Model):
name = models.CharField()
specialty = models.CharField()
class Team(models.Model):
captain = models.ForeignKey(Person)
vice_captain = models.ForeignKey(Person)
我有一个创建团队的表格...
class TeamForm(ModelForm):
class Meta:
model = Team
widgets['vice_captain'] = MySelectWidget()
我对表格还有一个额外的限制,即副队长必须与队长具有相同的专长。我已经以 clean 等形式实现了检查,但希望 UI 能够“过滤”自身。我决定不使用 ajax 来填充/过滤字段,而是将 html 'data-' 标签添加到小部件输出中,然后使用 javascript 隐藏选项。
我编写了一个与 Select 小部件一起使用的小部件(和 javascript)。在这里(注意这是从我的实际代码中简化的,但应该可以)。
class Select_with_Data(forms.Select):
# Not sure if this is necessary.
allow_multiple_selected = False
def render_option(self, selected_choices, option_value, option_label):
# This paragraph is copied from django Select.
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
# Only allow for a single selection.
selected_choices.remove(option_value)
else:
selected_html = ''
# My custom code to add data-specialty attributes to <option> tags.
# Get the object to filter upon.
obj = self.choices.queryset.get(pk=option_value)
# Get the data field.
data_field = getattr(obj, 'specialty', False)
# If the data field has a value set, add it to the return html.
# Need to check if the data_field has a pk (ie is a ForeignKey field), and handle it appropriately.
if data_field:
selected_html += ' data-{0}={1}'.format( 'specialty', str(getattr(data_field, 'pk', data_field)) )
# This paragraph is copied from django Select.
return format_html('<option value="{0}" {1}>{2}</option>',
option_value,
selected_html,
force_text(option_label))
但现在我决定我想要单选按钮,而不是选择列表。我的问题是,尝试在单选小部件的渲染器中使用与上述类似的代码失败,因为 self.choices.queryset 没有设置,所以我无法访问我需要的信息。 我怎样才能获得我需要的信息,这是做我想做的最好的方式吗?
我什至修改了核心 django 文件以查看查询集消失的位置。 RadioSelect 是 RendererMixin 的子类。 self.choices.queryset 在其 init、render 和 get_renderer 子功能期间可用? (函数是这个词吗?)。 RadioSelect 的渲染器是 RadioFieldRenderer,它是 ChoiceFieldRenderer 的子类。在它的 init 和渲染中,查询集已经消失(它设置了自己的 self.choices,但即使在 init 中的那一步之前,self.choices 也没有设置)。
【问题讨论】:
标签: django django-forms django-widget