Подтвердить что ты не робот

Django Admin: отношение OneToOne как встроенный?

Я собираю admin для приложения satchmo. Satchmo использует отношения OneToOne для расширения базовой модели Product, и я хотел бы отредактировать все это на одной странице.

Возможно ли иметь отношение OneToOne как Inline? Если нет, то каким образом можно добавить несколько полей на заданную страницу моего администратора, которые в конечном итоге будут сохранены в отношении OneToOne?

например:

class Product(models.Model):
    name = models.CharField(max_length=100)
    ...

class MyProduct(models.Model):
    product = models.OneToOne(Product)
    ...

Я попробовал это для своего администратора, но он не работает и, кажется, ожидает внешний ключ:

class ProductInline(admin.StackedInline):
    model = Product
    fields = ('name',)

class MyProductAdmin(admin.ModelAdmin):
    inlines = (AlbumProductInline,)

admin.site.register(MyProduct, MyProductAdmin)

Что вызывает эту ошибку: <class 'satchmo.product.models.Product'> has no ForeignKey to <class 'my_app.models.MyProduct'>

Это единственный способ сделать это Пользовательская форма?

изменить: Просто попробовал следующий код, чтобы добавить поля напрямую... также не работает:

class AlbumAdmin(admin.ModelAdmin):
    fields = ('product__name',)
4b9b3361

Ответ 1

Вполне возможно использовать встроенную линию для отношения OneToOne. Однако фактическое поле, определяющее отношение, должно быть на встроенной модели, а не на родительской - точно так же, как и для ForeignKey. Переключите его, и он будет работать.

Изменить после комментария: вы говорите, что родительская модель уже зарегистрирована у администратора: затем отмените регистрацию и перерегистрируйте.

from original.satchmo.admin import ProductAdmin

class MyProductInline(admin.StackedInline):
    model = MyProduct

class ExtendedProductAdmin(ProductAdmin):
    inlines = ProductAdmin.inlines + (MyProductInline,)

admin.site.unregister(Product)
admin.site.register(Product, ExtendedProductAdmin)

Ответ 2

Возможно использование наследования вместо отношения OneToOne

class Product(models.Model):
    name = models.CharField(max_length=100)
    ...

class MyProduct(Product):
    .....

Или использовать прокси-классы

class ProductProxy(Product)
    class Meta:
        proxy = True

в admin.py

class MyProductInlines(admin.StackedInline):
    model = MyProduct

class MyProductAdmin(admin.ModelAdmin):
    inlines = [MyProductInlines]

    def queryset(self, request):
        qs = super(MyProductAdmin, self).queryset(request)
        qs = qs.exclude(relatedNameForYourProduct__isnone=True)
        return qs

admin.site.register(ProductProxy, MyProductAdmin)

В этом варианте ваш продукт будет встроен.

Ответ 3

Ссылаясь на последний вопрос, что будет лучшим решением для нескольких подтипов. Например, класс Product с подтипом класса Book и подтип класса CD. Как показано здесь, вам нужно будет отредактировать продукт, а также элементы подтипа для книги и элементы подтипа для компакт-диска. Поэтому, даже если вы хотите добавить книгу, вы также получите поля для компакт-диска. Если вы добавите подтип, например. DVD, вы получаете три группы полей подтипа, в то время как на самом деле вам нужна только одна группа подтипов, в указанном примере: книги.