Django Admin: OnetoOne Relação como inline?
-
20-09-2019 - |
Pergunta
Estou montando o administrador para um aplicativo Satchmo. Satchmo usa as relações OnetoOne para estender a base Product
modelo, e eu gostaria de editar tudo em uma página.
É possível ter uma relação de otenone como inline? Caso contrário, qual é a melhor maneira de adicionar alguns campos a uma determinada página do meu administrador que acabará sendo salva na relação Onetoone?
por exemplo:
class Product(models.Model):
name = models.CharField(max_length=100)
...
class MyProduct(models.Model):
product = models.OneToOne(Product)
...
Eu tentei isso para o meu administrador, mas não funciona e parece esperar uma chave estrangeira:
class ProductInline(admin.StackedInline):
model = Product
fields = ('name',)
class MyProductAdmin(admin.ModelAdmin):
inlines = (AlbumProductInline,)
admin.site.register(MyProduct, MyProductAdmin)
Que lança este erro: <class 'satchmo.product.models.Product'> has no ForeignKey to <class 'my_app.models.MyProduct'>
É a única maneira de fazer isso um Formulário personalizado?
editar: Apenas tentei o código a seguir para adicionar os campos diretamente ... também não funciona:
class AlbumAdmin(admin.ModelAdmin):
fields = ('product__name',)
Solução
É perfeitamente possível usar uma embalagem para um relacionamento de Onetoone. No entanto, o campo real que define o relacionamento deve estar no modelo em linha, não o pai - da mesma maneira que para um estrangeiro. Mudar e funcionará.
Editar depois do comentário: Você diz que o modelo pai já está registrado no administrador: depois o registre e se registre novamente.
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)
Outras dicas
Referindo-se à última pergunta, qual seria a melhor solução para vários subtipos. Por exemplo, produto de classe com livro de classe de subtipo e CD da classe subtipo. A maneira mostrada aqui você precisaria editar um produto os itens gerais, além dos itens do subtipo para o livro e os itens do Subtype para CD. Portanto, mesmo se você deseja adicionar apenas um livro, você também recebe os campos para CD. Se você adicionar um Subtype, por exemplo, DVD, obterá três grupos de campo subtipos, enquanto realmente deseja apenas um grupo de subtipos, no exemplo mencionado: livros.
Talvez use a herança em vez de onetoone relacionamento
class Product(models.Model):
name = models.CharField(max_length=100)
...
class MyProduct(Product):
.....
Ou use aulas de proxy
class ProductProxy(Product)
class Meta:
proxy = True
em 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)
Nesta variante, seu produto estará em linha.
Você também pode tentar definir 'parent_link = true' em seu onetoonefield?
https://docs.djangoproject.com/en/dev/topics/db/models/#specification-the-parent-link-field