该模型的逻辑是:
Building
Rooms
Room
这是我的代码:
#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下拉菜单,它显示了“房间”表中的所有房间(包括其他建筑物中的房间)。
inside_room
在的内联中rooms,我需要将inside_room选择限制为rooms当前的选项building(当前正在由主BuildingAdmin窗体更改的建筑记录)。
rooms
building
我既无法找出limit_choices_to在模型中使用的方法,也无法找出如何正确地正确覆盖管理员的内联表单集(我觉得我应该以某种方式创建自定义内联表单,并传递的building_id将主表单设置为自定义内联,然后根据该字段将查询集限制为该字段的选择-但我只是无法将精力集中在如何做上)。
limit_choices_to
也许这对于管理站点来说太复杂了,但是似乎总会有用…
将请求实例用作obj的临时容器。重写内联方法formfield_for_foreignkey来修改查询集。这至少在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)