Dynamique des champs dans Django Admin
Je veux avoir des champs supplémentaires concernant la valeur d'un champ. À cet effet, je construire un administrateur personnalisé formulaire pour ajouter de nouveaux champs.
Liées à l'article sur le blog du jacobien Un c'est ce que je suis venu avec:
class ProductAdminForm(forms.ModelForm):
class Meta:
model = Product
def __init__(self, *args, **kwargs):
super(ProductAdminForm, self).__init__(*args, **kwargs)
self.fields['foo'] = forms.IntegerField(label="foo")
class ProductAdmin(admin.ModelAdmin):
form = ProductAdminForm
admin.site.register(Product, ProductAdmin)
Mais sur le terrain 'foo' ne s'affiche pas dans l'interface d'admin. Si j'ajoute le champ comme ça, tout fonctionne bien mais n'est pas aussi dynamique que nécessaire, pour ajouter les champs concernant la valeur d'un autre champ du modèle
class ProductAdminForm(forms.ModelForm):
foo = forms.IntegerField(label="foo")
class Meta:
model = Product
class ProductAdmin(admin.ModelAdmin):
form = ProductAdminForm
admin.site.register(Product, ProductAdmin)
Si il ya une méthode initialize que j'ai pour déclencher à nouveau pour faire le nouveau champ de travail? Ou est-il tout autre tentative?
OriginalL'auteur Stephan Hoyer | 2011-11-04
Vous devez vous connecter pour publier un commentaire.
Voici une solution au problème. Grâce à koniiiik j'ai essayé de résoudre ce problème en étendant l' *get_fieldsets* méthode
Si vous utilisez plusieurs balises html fieldsets veillez à ajouter le vers la droite fieldset en utilisant l'indice approprié.
Unknown field(s) (foo) specified for GlobalLabel. Check fields/fieldsets/exclude attributes of class GlobalLabelAdmin.
J'obtiens cette erreur, je ne sais pas pourquoi... pouvez-vous svp m'aider ?avez-vous été capable de comprendre cela? Je ne peux pas le faire fonctionner dans django 1.9.3, par exemple:
django.core.exceptions.FieldError: Unknown field(s) (dynamicfield1, dynamicfield2) specified for MyModel
il semble que vous n'avez pas défini de champ dans votre modèle.. pouvez-vous s'il vous plaît poster votre modèle de structure sur pastebin.com et le lien de partage?
bhushya: vous avez raison; les champs (dynamicfield1, etc.) ne sont pas définis sur mon modèle. Comme dans la question d'origine, je veux ajouter des champs dynamiquement dans un
ModelForm
, et laget_fieldsets
remplacer mentionnés ci-dessus ne semble pas fonctionner dans Django 1.9.3j'ai trouvé une solution potentielle pour Django 1.9.3, publié ci-dessous
OriginalL'auteur Stephan Hoyer
Cela fonctionne pour l'ajout dynamique de champs dans Django 1.9.3, en utilisant simplement un ModelAdmin classe (pas de ModelForm) et par substitution de
get_fields
. Je ne sais pas encore comment robuste qu'il est:OriginalL'auteur tehfink
Tandis que Jacob post pourrait marcher tout droit pour les réguliers
ModelForm
s (même si c'est plus d'un an et demi d'existence), l'admin est un peu différente de la matière.Tous les déclaratifs, de définition, de modèles, de formes ModelAdmins et autres joyeusetés fait un usage intensif des metaclasses de classe et de l'introspection. Même avec l'admin – lorsque vous dites à un
ModelAdmin
à l'utilisation d'un formulaire spécifique istead de la création d'un par défaut, il s'introspecte la classe. Il obtient la liste des champs et autres éléments de la classe elle-même sans son instanciation.Votre classe personnalisée, cependant, ne définit pas le formulaire supplémentaire de terrain au niveau de la classe, au lieu de cela, il ajoute dynamiquement un après il a été instancié, c'est trop tard pour le
ModelAdmin
de reconnaître ce changement.Une façon d'aller sur votre problème est peut-être à la sous-classe
ModelAdmin
et de remplacer songet_fieldsets
fait de méthode de instancier laModelForm
de classe et d'obtenir la liste des champs de l'instance au lieu de la classe. Vous devrez garder à l'esprit, cependant, que cela pourrait être un peu plus lent que le défaut de mise en œuvre.OriginalL'auteur koniiiik
Vous pouvez créer des dynamiques des champs et des fieldset en utilisant le formulaire de méta-classe. Exemple de code est donné ci-dessous. Ajouter la boucle logique que par les exigences que vous.
OriginalL'auteur santhoshnsscoe
Accepté la réponse ci-dessus a travaillé dans les anciennes versions de django, et c'est ainsi que je le faisais. Cela a rompu au plus tard django versions (je suis sur de 1,68 pour le moment, mais même ça, c'est vieux maintenant).
La raison pour laquelle il est aujourd'hui brisé est parce que tous les champs à l'intérieur des balises html fieldsets vous le retour de ModelAdmin.get_fieldsets() sont finalement passé comme champs= paramètre de modelform_factory(), qui vous donnera une erreur parce que les champs sur votre liste n'existent pas (et n'existera jusqu'à ce que votre formulaire est instancié et ses __ init __ est appelée).
Afin de résoudre ce problème, nous devons remplacer ModelAdmin.get_form() et de fournir une liste de champs qui ne comprennent pas les champs supplémentaires qui seront ajoutés plus tard. Le comportement par défaut de get_form est d'appeler get_fieldsets() pour cette information, et nous devons empêcher cela de se produire:
ModelAdmin.declared_fieldsets
a été supprimé dans Django 1.9Hmm.. eh bien, je suppose que lorsque je mettre à jour mes serveurs à 1,9, je vais avoir un peu de travail à faire 😉 Mais heureusement, j'ai répliqué la plupart des admin de la fonctionnalité ailleurs dans ma demande...
Aussi
django.contrib.admin.util
est maintenantdjango.contrib.admin.utils
Merci, ma réponse encore travailler autrement? Si oui, je vais le corriger.
OriginalL'auteur little_birdie
Stephan réponse est élégant, mais quand je l'ai utilisé dans les dj1.6 il fallait que le champ soit un n-uplet.
La solution complète ressemblait à ceci:
OriginalL'auteur rhoerbe
ne sais pas pourquoi ce n'est pas le travail, mais pourrait une solution de contournement possible de définir le champ statique (sur la forme), puis remplacer dans le
__init__
?OriginalL'auteur second
J'pendant une longue période ne pouvait pas résoudre un problème avec la dynamique de l'ajout de champs.
La solution "little_birdie" fonctionne vraiment. Merci Birdie))
La seule nuance est:
"L'auto.declared_fieldsets" devrait être remplacé par "l'auto.des balises html fieldsets".
J'ai utilisé la version 1.10. Peut-être que quelque chose a changé.
Si quelqu'un trouve un moyen encore plus simple et élégante solution de montrer ici.
Merci à tous )))
OriginalL'auteur Alex