J'essaie de créer un modèle de base pour afficher les valeurs de champ de l'instance sélectionnée, ainsi que leurs noms. Considérez-le simplement comme une sortie standard des valeurs de cette instance au format table, avec le nom du champ (verbose_name spécifiquement s'il est spécifié sur le champ) dans la première colonne et la valeur de ce champ dans la deuxième colonne.
Par exemple, disons que nous avons la définition de modèle suivante:
class Client(Model):
name = CharField(max_length=150)
email = EmailField(max_length=100, verbose_name="E-mail")
Je voudrais qu'il soit affiché dans le modèle comme ceci (supposons une instance avec les valeurs données):
Field Name Field Value
---------- -----------
Name Wayne Koorts
E-mail waynes@email.com
Ce que j'essaie de réaliser, c'est de pouvoir transmettre une instance du modèle à un modèle et de pouvoir l'itérer dynamiquement dans le modèle, quelque chose comme ceci:
<table>
{% for field in fields %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.value }}</td>
</tr>
{% endfor %}
</table>
Existe-t-il une manière "approuvée par Django" de faire cela? Cela semble être une tâche très courante, et je devrai le faire souvent pour ce projet particulier.
la source
Vous pouvez utiliser le sérialiseur de jeu de requêtes to-python de Django.
Mettez simplement le code suivant dans votre vue:
Et puis dans le modèle:
Son grand avantage est le fait qu'il gère les champs de relation.
Pour le sous-ensemble de champs, essayez:
la source
verbose_name
de passer le champ du?Enfin trouvé une bonne solution à cela sur la liste de diffusion des développeurs :
Dans la vue, ajoutez:
dans le modèle, ajoutez:
la source
FooForm
c'est unModelForm
, ne serait-il pas plus facile de simplement faireFooForm(instance=Foo.objects.get(pk=object_id)))
:?À la lumière de la sortie de Django 1.8 (et de la formalisation de l' API Model _meta , j'ai pensé que je mettrais à jour cela avec une réponse plus récente.
En supposant le même modèle:
Django <= 1,7
Django 1.8+ (API modèle _meta formalisée)
Dans l'exemple ci-dessous, nous utiliserons la méthode formalisée pour récupérer toutes les instances de champ d'un modèle via
Client._meta.get_fields()
:En fait, il a été porté à mon attention que ce qui précède est légèrement exagéré pour ce qui était nécessaire (je suis d'accord!). Le simple vaut mieux que le complexe. Je laisse ce qui précède pour référence. Cependant, pour l'afficher dans le modèle, la meilleure méthode serait d'utiliser un ModelForm et de transmettre une instance. Vous pouvez parcourir le formulaire (équivalent de l'itération sur chacun des champs du formulaire) et utiliser l'attribut label pour récupérer le verbose_name du champ de modèle et utiliser la méthode value pour récupérer la valeur:
Maintenant, nous rendons les champs dans le modèle:
la source
Voici une autre approche utilisant une méthode modèle. Cette version résout les champs de liste de sélection / choix, ignore les champs vides et vous permet d'exclure des champs spécifiques.
Puis dans votre modèle:
la source
except User.DoesNotExist:
?_meta.get_fields()
jusqu'à ce que je puisse le tester.Ok, je sais que c'est un peu tard, mais comme je suis tombé dessus avant de trouver la bonne réponse, quelqu'un d'autre pourrait le faire.
À partir de la documentation django :
la source
ordering = ['-id']
dansclass Meta:
votre objetmodels.py
. 2. puis utilisezBlog.objects.filter(name__startswith='Beatles').values()[0]
model
objet, vous allez à nouveau frapper la base de données juste pour obtenir les champs. Un moyen de contourner cela?Vous pouvez utiliser la
values()
méthode de aqueryset
, qui renvoie un dictionnaire. En outre, cette méthode accepte une liste de champs à sous-ensembles. Lavalues()
méthode ne fonctionnera pas avecget()
, vous devez donc utiliserfilter()
(reportez-vous à l' API QuerySet ).Dans
view
...Dans
detail.html
...Pour une collection d'instances renvoyées par le filtre:
En détail.html ...
la source
table
, donc j'ai besoin de chaquekey
s dans unth
. Comment faire cela sans boucles? Prenez n'importe quelle instance d'objet et parcourez-la pendantkey
s? Actuellement, je passe séparémentmodel_to_dict(Model())
pour leth
, mais je pense que c'est une instanciation d'objet inutile.get_object
la vue détaillée (mutilée en raison de la limitation du code en ligne sur les commentaires, et je ne pense pas que cela soit suffisant pour sa propre réponse compte tenu de la saturation de ce fil):def get_object(self, **kwargs): obj = super().get_object(**kwargs) obj = obj.__class__.objects.filter(pk=obj.pk).values()[0] return obj
obj.get_absolute_url
à cette liste sans dupliquer les lignes?J'ai utilisé https://stackoverflow.com/a/3431104/2022534 mais j'ai remplacé le model_to_dict () de Django par ceci pour pouvoir gérer ForeignKey:
Veuillez noter que je l'ai simplifié un peu en supprimant les parties de l'original dont je n'avais pas besoin. Vous voudrez peut-être les remettre.
la source
Vous pouvez demander à un formulaire de faire le travail pour vous.
Puis dans le modèle:
la source
DetailView
) fonctionne bien pour moi. Cependant, vous souhaiterez peut-être utiliser à lafield.label
place defield.name
.Il devrait vraiment y avoir un moyen intégré de le faire. J'ai écrit cet utilitaire
build_pretty_data_view
qui prend un objet modèle et une instance de formulaire (un formulaire basé sur votre modèle) et renvoie unSortedDict
.Les avantages de cette solution incluent:
SortedDict
.exclude()
liste de noms de champs pour exclure certains champs.Meta: exclude()
, mais que vous souhaitez toujours renvoyer les valeurs, ajoutez ces champs à laappend()
liste facultative .Pour utiliser cette solution, ajoutez d'abord ce fichier / cette fonction quelque part, puis importez-le dans votre fichier
views.py
.utils.py
Alors maintenant,
views.py
tu pourrais faire quelque chose comme çaMaintenant, dans votre
my-template.html
modèle, vous pouvez parcourir les données comme ceci ...Bonne chance. J'espère que cela aide quelqu'un!
la source
Ci-dessous est le mien, inspiré de shacker
get_all_fields
. Il obtient un dict d'une instance de modèle, si le champ de relation rencontre, puis attribue récursivement la valeur du champ à un dict.Cette fonction est principalement utilisée pour vider une instance de modèle dans des données json:
la source
Au lieu d'éditer chaque modèle, je recommanderais d'écrire une balise de modèle qui renverra tous les champs de n'importe quel modèle donné.
Chaque objet a une liste de champs
._meta.fields
.Chaque objet champ a un attribut
name
qui renverra son nom et la méthodevalue_to_string()
fournie avec votre modèleobject
renverra sa valeur.Le reste est aussi simple que cela est dit dans la documentation Django .
Voici mon exemple à quoi pourrait ressembler ce templatetag:
la source
Ouais ce n'est pas joli, tu devras faire ton propre emballage. Jetez un œil à l' application Databrowse intégrée , qui possède toutes les fonctionnalités dont vous avez vraiment besoin.
la source
Cela peut être considéré comme un hack, mais je l'ai fait avant d'utiliser modelform_factory pour transformer une instance de modèle en un formulaire.
La classe Form contient beaucoup plus d'informations qui sont très faciles à parcourir et qui serviront le même objectif au détriment d'un peu plus de frais généraux. Si vos ensembles de tailles sont relativement petits, je pense que l'impact sur les performances serait négligeable.
Le seul avantage en plus de la commodité est bien sûr que vous pouvez facilement transformer la table en une grille de données modifiable à une date ultérieure.
la source
J'ai mis au point la méthode suivante, qui fonctionne pour moi car dans tous les cas, le modèle aura un ModelForm associé.
Voici un extrait du modèle que j'utilise pour cette vue particulière:
L'avantage de cette méthode est que je peux choisir modèle par modèle l'ordre dans lequel je souhaite afficher les étiquettes de champ, en utilisant le tuple passé à GetModelData et en spécifiant les noms de champ. Cela me permet également d'exclure certains champs (par exemple, une clé étrangère utilisateur) car seuls les noms de champs passés via le tuple sont intégrés dans le dictionnaire final.
Je ne vais pas accepter cela comme réponse car je suis sûr que quelqu'un peut proposer quelque chose de plus "Djangonic" :-)
Mise à jour: je choisis ceci comme réponse finale car c'est la plus simple de celles données qui fait ce dont j'ai besoin. Merci à tous ceux qui ont apporté des réponses.
la source
Solution Django 1.7 pour moi:
Les variables sont exactes à la question, mais vous devriez certainement être en mesure de disséquer cet exemple
La clé ici est d'utiliser à peu près
.__dict__
le modèleviews.py :
modèle :
dans le modèle, j'ai utilisé un filtre pour accéder au champ dans le dict
filters.py :
la source
J'utilise ceci, https://github.com/miracle2k/django-tables .
la source
Cette approche montre comment utiliser une classe comme ModelForm de django et une balise de modèle comme {{form.as_table}}, mais que toute la table ressemble à une sortie de données, pas à un formulaire.
La première étape a été de sous-classer le widget TextInput de django:
Ensuite, j'ai sous-classé ModelForm de django pour échanger les widgets par défaut pour les versions en lecture seule:
Ce sont les seuls widgets dont j'avais besoin. Mais il ne devrait pas être difficile d'étendre cette idée à d'autres widgets.
la source
Juste une modification de @wonder
Laissez Django gérer tous les autres champs autres que les champs associés. Je sens que c'est plus stable
la source
Jetez un œil à l' application django-etc . Il a une
model_field_verbose_name
balise de modèle pour obtenir un nom de champ détaillé à partir de modèles: http://django-etc.rtfd.org/en/latest/models.html#model-field-template-tagsla source
Je viens de tester quelque chose comme ça en shell et semble faire son travail:
Notez que si vous voulez une représentation str () pour les objets étrangers, vous devez la définir dans leur méthode str . À partir de là, vous avez dict des valeurs pour l'objet. Ensuite, vous pouvez rendre une sorte de modèle ou autre.
la source
Django> = 2.0
Ajoutez
get_fields()
à votremodels.py
:Puis appelez-le comme
object.get_fields
sur votretemplate.html
:la source
la source