Django管理员具有相同模型的多个内联

时间:2012-03-16 14:20:59

标签: django django-forms django-admin

我在管理界面中遇到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都填充了数据...前缀管理得不好......

  • 在我看不到的代码中是否有任何错误和明显的内容?
  • 在管理界面中有两个获得假装布局的其他好选项吗?

1 个答案:

答案 0 :(得分:4)

比使用自定义查询集的内联更好的解决方案是将Proxy Modelscustom 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,
           ]