【问题标题】:Django admin with multiple inlines of the same model具有同一模型的多个内联的 Django 管理员
【发布时间】:2012-03-16 14:20:58
【问题描述】:

我在管理界面中遇到 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)

使用此代码,我设法在 Hotel 模型的管理界面中获得了两个独立的 StackedInlines,它们中的每一个都允许仅选择正确的 itemprovided 子集。太好了。

问题:如果一个提供了一个项目,例如在房间的 StackedInline 中;两个 StackedInlines 都填充了数据...前缀管理不善...

  • 我没有看到的代码中有什么错误和明显的地方吗?
  • 有没有其他好的选择二在管理界面中获取伪装的布局?

【问题讨论】:

  • 前缀是否出现在模板中,或者它们是否被跳过?另外,检查你重新定义的 __init__ 是否正在运行。
  • (我现在无法检查它,因为我不在我的电脑前)....前缀“房间”应用于第一个表单集,但第二个也需要“房间”作为前缀而不是它自己的“服务”。

标签: django django-forms django-admin


【解决方案1】:

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

【讨论】:

  • 我刚刚尝试了您的解决方案,它几乎可以工作。但它向我展示了解决问题的方法。总结:1)您的解决方案解决了我遇到的前缀问题,每个表单集都可以正常工作; 2)我仍然需要过滤每个内联表单集的查询集,因为它不在我必须过滤的itemprovided 中(可能还没有itemprovideds),而是在itemprovided__item
猜你喜欢
  • 2011-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 2015-06-10
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多