在 Django 中使用 limit_choices_to 中的字段值
Use field value in limit_choices_to in Django
我有两个模型 Project
和 Group
。我的小组属于一个特定的项目。我的组有字段 project = ForeignKey(Project)
和 parent = ForeignKey('self')
.
我可以使用 limit_choices_to
来确保外键 parent
中的选项只包含同一项目中的组吗?
我在想
def limit_choices_to(self):
return {'project': self.project}
这在模型级别是不可能的,但您可以在表单的构造函数中更改此字段的查询集。
class GroupForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(GroupForm, self).__init__(*args, **kwargs)
if self.instance.project:
self.fields['parent'].queryset = Group.objects.filter(
project=self.instance.project)
更新:要在管理员中执行此操作,您必须设置 ModelAdmin
:
的 form
属性
class GroupAdmin(admin.ModelAdmin):
form = GroupForm
对于管理部分,我发现了一种很老套的方法。我的示例是 admin.StackedInline,但几乎可以肯定它适用于普通 ModelAdmin。我把它留在这里以防万一有人喜欢这个解决方案:
class ProfessionalInline(admin.StackedInline):
model = Professional
fieldsets = [
('Research information', {
'fields': ('team', 'projects')
}),
('Profile information', {
'fields': ('age', 'gender', 'receive_emails')
})]
def get_parent_object_from_request(self, request):
"""
Returns the parent object from the request or None.
Note that this only works for Inlines, because the `parent_model`
is not available in the regular admin.ModelAdmin as an attribute.
"""
resolved = resolve(request.path_info)
if resolved.kwargs:
return self.parent_model.objects.get(pk=resolved.kwargs['object_id'])
return None
def formfield_for_manytomany(self, db_field, request, **kwargs):
'''Extremely hacky'''
account = self.get_parent_object_from_request(request)
if db_field.name == 'projects':
kwargs['queryset'] = Project.objects.filter(team=account.professional.team)
return super().formfield_for_manytomany(db_field, request, **kwargs)
我有两个模型 Project
和 Group
。我的小组属于一个特定的项目。我的组有字段 project = ForeignKey(Project)
和 parent = ForeignKey('self')
.
我可以使用 limit_choices_to
来确保外键 parent
中的选项只包含同一项目中的组吗?
我在想
def limit_choices_to(self):
return {'project': self.project}
这在模型级别是不可能的,但您可以在表单的构造函数中更改此字段的查询集。
class GroupForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(GroupForm, self).__init__(*args, **kwargs)
if self.instance.project:
self.fields['parent'].queryset = Group.objects.filter(
project=self.instance.project)
更新:要在管理员中执行此操作,您必须设置 ModelAdmin
:
form
属性
class GroupAdmin(admin.ModelAdmin):
form = GroupForm
对于管理部分,我发现了一种很老套的方法。我的示例是 admin.StackedInline,但几乎可以肯定它适用于普通 ModelAdmin。我把它留在这里以防万一有人喜欢这个解决方案:
class ProfessionalInline(admin.StackedInline):
model = Professional
fieldsets = [
('Research information', {
'fields': ('team', 'projects')
}),
('Profile information', {
'fields': ('age', 'gender', 'receive_emails')
})]
def get_parent_object_from_request(self, request):
"""
Returns the parent object from the request or None.
Note that this only works for Inlines, because the `parent_model`
is not available in the regular admin.ModelAdmin as an attribute.
"""
resolved = resolve(request.path_info)
if resolved.kwargs:
return self.parent_model.objects.get(pk=resolved.kwargs['object_id'])
return None
def formfield_for_manytomany(self, db_field, request, **kwargs):
'''Extremely hacky'''
account = self.get_parent_object_from_request(request)
if db_field.name == 'projects':
kwargs['queryset'] = Project.objects.filter(team=account.professional.team)
return super().formfield_for_manytomany(db_field, request, **kwargs)