Администратор Django с несколькими строками одной модели - PullRequest
1 голос
/ 16 марта 2012

У меня проблема с префиксами 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 в интерфейсе администратора для модели отеля, каждый из которых позволял выбрать только правильное подмножество itemprovideds. Отлично.

Проблема: , если есть созданная одна итерация, например, в StackedInline комнаты; оба StackedInline заполнены данными ... префиксы плохо управляются ...

  • Что-то не так и очевидно в коде, который я не вижу?
  • Есть ли другой хороший вариант получения предустановленного макета в интерфейсе администратора?

1 Ответ

4 голосов
/ 20 марта 2012

Лучшим решением, чем встроенные функции с пользовательским набором запросов, является использование прокси-моделей с пользовательским менеджером , который добавляет фильтрацию по умолчанию.С этим решением вы можете легко повторно использовать эти модели за пределами администратора:

# 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,
           ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...