I am putting together the admin for a satchmo application. Satchmo uses OneToOne relations to extend the base
Product model, and I'd like to edit it all on one page.
It is possible to have a OneToOne relation as an Inline? If not, what is the best way to add a few fields to a given page of my admin that will eventually be saved into the OneToOne relation?
class Product(models.Model): name = models.CharField(max_length=100) ... class MyProduct(models.Model): product = models.OneToOne(Product) ...
I tried this for my admin but it does not work, and seems to expect a Foreign Key:
class ProductInline(admin.StackedInline): model = Product fields = ('name',) class MyProductAdmin(admin.ModelAdmin): inlines = (AlbumProductInline,) admin.site.register(MyProduct, MyProductAdmin)
Which throws this error:
<class 'satchmo.product.models.Product'> has no ForeignKey to <class 'my_app.models.MyProduct'>
Is the only way to do this a Custom Form?
edit: Just tried the following code to add the fields directly... also does not work:
class AlbumAdmin(admin.ModelAdmin): fields = ('product__name',)
It's perfectly possible to use an inline for a OneToOne relationship. However, the actual field defining the relationship has to be on the inline model, not the parent one - in just the same way as for a ForeignKey. Switch it over and it will work.
Edit after comment: you say the parent model is already registered with the admin: then unregister it and re-register.
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)
Maybe use inheritance instead OneToOne relationship
class Product(models.Model): name = models.CharField(max_length=100) ... class MyProduct(Product): .....
Or use proxy classes
class ProductProxy(Product) class Meta: proxy = True
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)
In this variant your product will be in inline.