我在管理界面中遇到StackedInlines前缀问题。我会尝试发布所有必要的代码。
models.py(简短)
##### Base classes
class BaseItem(models.Model):
pass
class BaseProvider(PolymorphicModel):
items = models.ManyToManyField(BaseItem, through="ItemProvided")
class ItemProvided(models.Model):
item = models.ForeignKey(BaseItem)
provider = models.ForeignKey(BaseProvider)
price = models.IntegerField()
##### Implementing ones
class Hotel(BaseProvider):
pass
class Room(BaseItem):
pass
class Service(BaseItem):
pass
这个层次结构如下:酒店是提供房间或服务的提供者。
admin.py(简要)
#### Creating admin.StackedInline for Rooms
class RoomInlineFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
kwargs.update({'prefix':'room'})
super(RoomInlineFormSet, self).__init__(*args, **kwargs)
class HotelRoomInline(admin.StackedInline):
# This class also filters 'item' choiceField in order to have only ItemProvideds which are rooms
model = ItemProvided
formset = RoomInlineFormSet
#### Creating admin.StackedInline for Services
class ServiceInlineFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
kwargs.update({'prefix':'service'})
super(ServiceInlineFormSet, self).__init__(*args, **kwargs)
class HotelServiceInline(admin.StackedInline):
# This class also filters 'item' choiceField in order to have only ItemProvideds which are services
model = ItemProvided
formset = ServiceInlineFormSet
#### Adding inlines to HotelAdmin and model to admin interface
class HotelAdmin(admin.ModelAdmin):
inlines = [
HotelRoomInline,
HotelServiceInline,
]
admin.site.register(Hotel, HotelAdmin)
使用此代码,我设法在酒店模型的管理界面中获得两个独立的StackedInlines,每个都允许仅选择适当的itemprovided子集。大。
问题:如果在房间的StackedInline中创建了一个itemprovided,例如; StackedInlines都填充了数据...前缀管理得不好......
答案 0 :(得分:4)
比使用自定义查询集的内联更好的解决方案是将Proxy Models与custom manager一起使用,这会添加默认过滤。使用该解决方案,您可以轻松地在管理员之外重复使用这些模型:
# models.py
class HotelRoomManager(models.Manager):
def get_query_set(self):
return super(HotelRoomManager, self).get_query_set().filter(prefix='room')
class HotelRoom(ItemProvided):
""" Only ItemProvided with prefix=room """
objects = HotelRoomManager()
class Meta:
proxy = True
class HotelServiceManager(models.Manager):
def get_query_set(self):
return super(HotelServiceManager, self).get_query_set().filter(prefix='service')
class HotelService(ItemProvided):
""" Only ItemProvided with prefix=service"""
objects = HotelServiceManager()
class Meta:
proxy = True
#### admin.py
class HotelRoomInline(admin.StackedInline):
model = HotelRoom
class HotelServiceInline(admin.StackedInline):
model = HotelService
class HotelAdmin(admin.ModelAdmin):
inlines = [
HotelRoomInline,
HotelServiceInline,
]