Администратор Django: отношение OneToOne как встроенное? - PullRequest
58 голосов
/ 16 ноября 2009

Я собираю админа для приложения 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'>

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

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

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

Ответы [ 4 ]

73 голосов
/ 16 ноября 2009

Вполне возможно использовать встроенные отношения 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)
6 голосов
/ 28 сентября 2012

Возможно использовать наследование вместо отношения 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)

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

6 голосов
/ 14 марта 2010

Обращаясь к последнему вопросу, что было бы лучшим решением для нескольких подтипов. E.g класс Продукт с подтипом класса Book и подтипом класса CD. Показанным здесь способом вам нужно будет отредактировать продукт, общие элементы плюс элементы подтипа для книги И элементы подтипа для CD. Таким образом, даже если вы хотите добавить только книгу, вы также получите поля для CD. Если вы добавите подтип, например, На DVD вы получаете три группы полей подтипов, в то время как в приведенном примере вам нужна только одна группа подтипов: books.

1 голос
/ 14 декабря 2012

Вы также можете попробовать установить parent_link = True в OneToOneField?

https://docs.djangoproject.com/en/dev/topics/db/models/#specifying-the-parent-link-field

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...