2017-10-04 3 views
0

Je suis assez nouveau avec python et django et je m'excuse si le sujet était déjà couvert, mais je ne trouverais pas de réponse à ma question.Comment obtenir une valeur à partir d'un objet apparenté dans un template django

Je cours theese dans mon models.py

class Category(models.Model): 
    category_type = models.CharField(max_length=50) 
    description = models.TextField() 

    def __unicode__(self): 
     return self.category_type 

class Area(models.Model): 
    area_type = models.CharField(max_length=50) 
    description = models.TextField() 

    def __unicode__(self): 
     return self.area_type 

class Topic(models.Model): 
    topic_type = models.CharField(max_length=50) 
    description = models.TextField() 

    def __unicode__(self): 
     return self.topic_type 

class Tag(models.Model): 
    tag_type = models.CharField(max_length=50) 
    description = models.TextField() 

    def __unicode__(self): 
     return self.tag_type 

class GenericRecord(models.Model): 
    document_title = models.CharField(max_length=500) 
    category = models.ForeignKey("Category") 
    area = models.ForeignKey("Area") 
    topic = models.ForeignKey("Topic") 
    tag = models.ForeignKey("Tag") 
    note = models.TextField(null=True, blank=True) 
    link = models.TextField(null=True, blank=True) 
    file_upload = models.FileField(upload_to='GenericRecord/', null=True, blank=True) 

    class Meta: 
     abstract = True 


class Document(GenericRecord): 
    code = models.CharField(max_length=500, null=True, blank=True) 
    reference = models.CharField(max_length=500) 
    issue_date = models.DateField(auto_now=False, auto_now_add=False) 
    validation_date = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True) 

    def get_admin_url(self): 
     return reverse("admin:%s_%s_change" % (self._meta.app_label, self._meta.model_name), args=(self.id,)) 

    def __unicode__(self): 
     if self.code: 
      return "%s-%s" % (self.code, self.document_title) 
     else: 
      return "--%s" % self.document_title 

Et ce morceau de code dans views.py

def documents_list(request): 
    # Generate counts of some of the main objects 
    num_docs=Document.objects.all().count() 
    docs=Document.objects.all() 
    num_articles=Article.objects.all().count() 
    articles=Article.objects.all() 
    template='documents_management.html' 

    for object in docs: 
     object.fields = dict((field.name, field.value_to_string(object)) for field in object._meta.fields) 

    # Render the HTML template documents_management.html with the data in the context variable 
    return render(request,template, context={'docs':docs, 'num_docs':num_docs,'docs':docs, 'num_articles':num_articles, 'articles':articles}) 

Dans le modèle que je suis en train d'obtenir une table avec toutes les valeurs, mais pour les objets connexes, je reçois la clé primaire (bien sûr).

Voici le code dans mon modèle:

<table class="w3-table-all"> 
    {% for object in docs %} 
     {%if forloop.first %} 

      <tr> 
      {% for field, value in object.fields.iteritems %} 
       <th>{{ field }}</th> 
      {% endfor %} 
      </tr> 

     {%endif%} 
    {% endfor %} 

    {% for object in docs %}  
     {% for field, value in object.fields.iteritems %} 

      <td>{{ value }}</td> 

     {% endfor %} 
     </tr> 
    {% endfor %} 
</table> 

What I see in my browser

Ma question est, comment puis-je l'objet Catégorie, Zone etc ... afin d'obtenir le category_type, area_type etc. . valeur?

Merci!

Répondre

0

Voici un excellent exemple de la documentation: https://docs.djangoproject.com/en/1.11/intro/tutorial03/#use-the-template-system

Ce que vous recherchez est la partie question.choice_set.all.

UPDATE en raison d'un soupçon de mauvais style

Comme mentionné par daniel vous devez fossé la méthode Field.to_value_string.

Depuis que je ne suis pas fan code implicite je recommande toujours aux modèles de code le plus explicite possible, ici serait par ma version de votre modèle

<table class="w3-table-all"> 
    {% for doc in docs %} 

     {% if forloop.first %} 
      <tr> 
       <th>Document Title</th> 
       <th>Category Type</th> 
       <th>Area Type</th> 
       <th>...</th> 
      </tr> 
     {% else %} 
      <tr> 
       <td>{{ doc.document_title }}</td> 
       <td>{{ doc.category.category_type }}</td> 
       <td>{{ doc.area.area_type }}</td> 
       <td>...</td> 
      </tr> 
     {% endif %} 

    {% endfor %} 
</table> 

Ce que je changé:

  • seulement une pour la boucle, vous avez commencé avec le if forloop.first vous pourriez également finir avec l'autre cas
  • refacturé object à doc parce que les objets sont souvent utilisés dans django pour le mode les gestionnaires de l
  • ajouter les champs explicites doc.area.area_type, cela empêchera un nouveau champ dans le modèle apparaît également dans le modèle, mais ici, je recommande un explicite sur un style de codage implicite

vous pouvez également supprimer de document_list :

for object in docs: 
    object.fields = dict((field.name, field.value_to_string(object)) for field in object._meta.fields) 
+0

Ceci est pour les relations inverses. OP veut montrer les relations à terme. –

+0

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et fournir le lien pour référence. Les réponses à lien uniquement peuvent devenir invalides si la page liée change. - [De l'avis] (/ review/low-quality-posts/17523854) – horcrux

+0

Hey, merci pour la rétroaction vous avez absolument raison. J'ai mis à jour ma réponse pour l'espérer compenser ^^ –

0

Le problème est dans votre utilisation de Field.value_to_string. Comme le montre la docstring sur cette méthode, c'est pour la sérialisation, pas pour l'affichage des valeurs.

Une façon beaucoup plus simple et plus efficace de le faire serait d'utiliser getattr, qui obtient la valeur réelle; le modèle prendra alors soin de convertir ceux-ci en une chaîne, qui dans le cas des clés étrangères appellera la méthode __unicode__ des objets liés.

object.fields = dict((field.name, getattr(obj, field.name)) for field in object._meta.fields) 
+0

merci pour la clarification. Maintenant, je cherche un moyen de commander la valeur ... – MasVincy