Je rassemble l'administrateur pour une application satchmo. Satchmo utilise les relations OneToOne pour étendre le modèle de base Product
, et je voudrais tout modifier sur une seule page.
Il est possible d'avoir une relation OneToOne en tant que Inline? Sinon, quelle est la meilleure façon d'ajouter quelques champs à une page donnée de mon administrateur qui seront finalement enregistrés dans la relation OneToOne?
par exemple:
class Product(models.Model):
name = models.CharField(max_length=100)
...
class MyProduct(models.Model):
product = models.OneToOne(Product)
...
J'ai essayé cela pour mon administrateur mais cela ne fonctionne pas et semble attendre une clé étrangère:
class ProductInline(admin.StackedInline):
model = Product
fields = ('name',)
class MyProductAdmin(admin.ModelAdmin):
inlines = (AlbumProductInline,)
admin.site.register(MyProduct, MyProductAdmin)
Ce qui jette cette erreur: <class 'satchmo.product.models.Product'> has no ForeignKey to <class 'my_app.models.MyProduct'>
La seule façon de le faire est-elle Formulaire personnalisé ?
edit: Je viens d'essayer le code suivant pour ajouter directement les champs ... ne fonctionne pas non plus:
class AlbumAdmin(admin.ModelAdmin):
fields = ('product__name',)
Il est parfaitement possible d'utiliser un inline pour une relation OneToOne. Cependant, le champ réel définissant la relation doit se trouver sur le modèle en ligne, pas sur le modèle parent - de la même manière que pour une ForeignKey. Basculez-le et cela fonctionnera.
Modifier après commentaire: vous dites que le modèle parent est déjà enregistré auprès de l'administrateur: puis désenregistrez-le et réenregistrez-vous.
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)
En référence à la dernière question, quelle serait la meilleure solution pour plusieurs sous-types. Par exemple, classe Produit avec sous-type classe Livre et sous-type classe CD. Comme indiqué ici, vous devez modifier un produit, les éléments généraux plus les éléments de sous-type pour le livre ET les éléments de sous-type pour le CD. Ainsi, même si vous ne souhaitez ajouter qu'un livre, vous obtenez également les champs pour CD. Si vous ajoutez un sous-type, par exemple DVD, vous obtenez trois groupes de champs de sous-types, alors que vous ne voulez en fait qu'un seul groupe de sous-types, dans l'exemple mentionné: les livres.
Peut-être utiliser l'héritage à la place de la relation OneToOne
class Product(models.Model):
name = models.CharField(max_length=100)
...
class MyProduct(Product):
.....
Ou utilisez des classes proxy
class ProductProxy(Product)
class Meta:
proxy = True
dans 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)
Dans cette variante, votre produit sera en ligne.
Vous pouvez également essayer de définir "parent_link = True" sur votre OneToOneField?
https://docs.djangoproject.com/en/dev/topics/db/models/#specifying-the-parent-link-field