在管理员中以内联形式限制外键选择 [英] Limit foreign key choices in select in an inline form in admin
问题描述
模型的逻辑是:
- A
建立
有很多房间
- A
房间
可能在另一个 - A
房间
只能在同一栋楼内的另一个房间
<这个是棘手的部分)
- A
Building
has manyRooms
- A
Room
may be inside anotherRoom
(a closet, for instance--ForeignKey on 'self') - A
Room
can only be inside anotherRoom
in the same building (this is the tricky part)
这里是我的代码:
#spaces/models.py
from django.db import models
class Building(models.Model):
name=models.CharField(max_length=32)
def __unicode__(self):
return self.name
class Room(models.Model):
number=models.CharField(max_length=8)
building=models.ForeignKey(Building)
inside_room=models.ForeignKey('self',blank=True,null=True)
def __unicode__(self):
return self.number
和:
#spaces/admin.py
from ex.spaces.models import Building, Room
from django.contrib import admin
class RoomAdmin(admin.ModelAdmin):
pass
class RoomInline(admin.TabularInline):
model = Room
extra = 2
class BuildingAdmin(admin.ModelAdmin):
inlines=[RoomInline]
admin.site.register(Building, BuildingAdmin)
admin.site.register(Room)
内联将只显示当前建筑物中的房间(这是我想要的)。问题是,对于 inside_room
下拉菜单,它会显示房间表格中的所有房间(包括其他建筑物中的房间)。
The inline will display only rooms in the current building (which is what I want). The problem, though, is that for the inside_room
drop down, it displays all of the rooms in the Rooms table (including those in other buildings).
在房间的内联
中,我需要限制 inside_room
房间
,它们位于当前建筑
(建筑物记录正在由主要 BuildingAdmin
表单)。
In the inline of rooms
, I need to limit the inside_room
choices to only rooms
which are in the current building
(the building record currently being altered by the main BuildingAdmin
form).
我无法找出一种在模型中使用 limit_choices_to
的方法,也不能弄清楚如何正确地覆盖管理员的内联表单(我觉得我应该以某种方式创建一个自定义的内联表单,将主窗体的building_id传递给自定义的内联,然后基于这一点限制该字段的选择的查询器 - 但是我只是不能包围我的头脑如何做到这一点)。
I can't figure out a way to do it with either a limit_choices_to
in the model, nor can I figure out how exactly to override the admin's inline formset properly (I feel like I should be somehow create a custom inline form, pass the building_id of the main form to the custom inline, then limit the queryset for the field's choices based on that--but I just can't wrap my head around how to do it).
也许这对于管理网站来说太复杂了,但它似乎是一般的东西有用的...
Maybe this is too complex for the admin site, but it seems like something that would be generally useful...
推荐答案
将请求实例用作obj的临时容器。
重写Inline方法formfield_for_foreignkey来修改查询集。
这个工作至少在django 1.2.3上。
Used request instance as temporary container for obj. Overrided Inline method formfield_for_foreignkey to modify queryset. This works at least on django 1.2.3.
class RoomInline(admin.TabularInline):
model = Room
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
field = super(RoomInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'inside_room':
if request._obj_ is not None:
field.queryset = field.queryset.filter(building__exact = request._obj_)
else:
field.queryset = field.queryset.none()
return field
class BuildingAdmin(admin.ModelAdmin):
inlines = (RoomInline,)
def get_form(self, request, obj=None, **kwargs):
# just save obj reference for future processing in Inline
request._obj_ = obj
return super(BuildingAdmin, self).get_form(request, obj, **kwargs)
这篇关于在管理员中以内联形式限制外键选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!