Génération de documents PDF via Latex
#1
Bonjour,

Je crée un nouveau sujet car le précédent (Personnalisation) était trop vague.

À partir du module Activities, je voudrais générer des lettres de convocation à envoyer en courrier papier (PDF).

Pour cela, je me suis basé sur la vue export.py et sa fonction export_as_pdf du module Billing comme vous me l'aviez conseillé puis j'ai créé un template .tex ad hoc.

Je ne sais pas insérer un bouton de génération de document qui pointerait par exemple vers /activities/generate_pdf/n°_activité et quand je me rends manuellement sur cette adresse, une erreur 404 apparaît.

Voici les données que je voudrais transmettre à mon template :
  1. civilité, prénom, nom et adresse d'un contact (participant d'une activité) ou nom et adresse d'une organisation (autre fiche liée à cette activité) ;
  2. le jour, l'heure et les autres participants de cette même activité.
  Répondre
#2
Citation :Je ne sais pas insérer un bouton de génération de document qui pointerait par exemple vers /activities/generate_pdf/n°_activité et quand je me rends manuellement sur cette adresse, une erreur 404 apparaît.

Avez-vous défini ladite vue (la fonction python qui prend un ID d'activité en paramètre et renvoie un PDF) ? Avez-vous configuré le fichier activities/urls.py pour prendre en compte cette vue ; si ce n'est pas le cas l'erreur 404 est évidement normale...

Pour la création d'un bouton, c'est expliqué dans le tutoriel de création de module (dans doc/fr/Didacticiel - Coder un module.rst). Le plus propre est de créer votre propre app, avec son urls.py, sa vue de génération de pdf, le bouton que vous configurez (dans populate.py) pour se mettre dans la vue de détail des activités. Du coup votre url ressemblera plutôt a /my_app/activity/gen_pdf/activity_id, mais ce n'est pas gênant je pense.
  Répondre
#3
J'ai défini la vue ainsi que le fichier urls, mais je pense que je n'ai pas bien codé ma fonction.

Mon problème, c'est que je n'arrive pas à comprendre comment faire remonter une variable qui n'est pas dans la table activities_activity... En fait, je voudrais faire apparaître dans mon template Latex la variable date de rendez-vous, la variable lieu (que j'ai rajoutée dans la classe activity) – celles-là sont dans cette table – mais je voudrais aussi y mettre les variables other_participants et participating_users qui ne sont pas directement dans cette même table.

Je commence à faire des nœuds avec toutes ces données.

Le résultat, c'est que soit je n'arrive pas à définir correctement les variables dans ma view soit j'obtiens toujours l'erreur 404.

Je continue de chercher mais je commence à désespérer car tout le reste fonctionne à merveille.
  Répondre
#4
Les Activités utilisent des Relations entre elles et leurs participants. La classe Activity possède une méthode get_participant_relations() qui permet d'obtenir ces relations en particuliers ; rien de spécifique aux Activités la dedans, vous pourriez obtenir ces Relations avec la bonne requête sur la table des relations ; comme obtenir les participants est quelque chose qui revient plusieurs fois dans le code cette méthode facilite juste la vie.

Les participants seront alors obtenus en accédant à l'objet de la relation (par opposition au sujet, l'Activité dans le cas présent) par le bais de l'attribut object_entity (de type CremeEntity), et d'appeler sur cette entité la méthode get_real_entity() pour obtenir l'entité de classe finale correspondante ; il s'agira bien d'un Contact car ce type de relation (soit 'a pour participant') est toujours entre une Activité et un Contact.

Ce qui donnera quelque chose comme ça:

Code :
for rel in my_activity.get_participant_relations():
    print 'Participe:', rel.object_entity.get_real_entity()

Ça peut paraître complexe mais les concepts d'Entité et Relations sont au coeur de Creme, et bien comprendre comment ça marche est important.

Pour les soit disant variables other_participants et participating_users, vous confondez je pense avec le formulaire des Activités (et donc 'variables' n'a en fait aucun sens ici) ; regardez son fonctionnement et vous verrez que ces 2 champs servent bien à construire des relations au final.
  Répondre
#5
J'ai procédé par élimination, mais j'ai encore des problèmes...

La partie Latex et génération de PDF fonctionne, j'ai remplacé les variables par des valeurs fixes et le test est concluant.

Par contre, j'ai suivi vos précieux conseils sur les relations (je commence à entrevoir leur importance !) mais j'arrive toujours sur une erreur. Erreur 500 maintenant avec en commentaire :
Code :
AttributeError: 'function' object has no attribute 'object_entity'
  Répondre
#6
Par acquis de conscience j'ai testé mon code : il marche très bien. L'erreur que vous obtenez est très parlante : vous essayez (par exemple) de faire rel.object_entity, mais rel est une fonction/méthode et pas une instance de Relation (alors que dans mon code c'est bien le cas) ; peut-être avez-vous oublié des parenthèses pour appeler une fonction (et non pas l'utiliser telle quelle).
C'est un problème de connaissance de Python, et si vous souhaitez en écrire, il va malheureusement vous falloir apprendre à debugger votre code (vous pouvez simplement mettre des print pour comprendre ce que vous manipulez, et scruter votre terminal) et comprendre les erreurs, surtout quand elles sont aussi triviales qu'ici (ce n'est pas toujours le cas). Vous pouvez facilement tester des bouts de code dans le shell django (manage.py shell) ; si vous avez installé l'app django_extensions ainsi que ipython vous avez aussi une commande shell_plus encore plus conviviale.
  Répondre
#7
Je n'avais pas pensé au shell. C'est vrai qu'avec l'interface graphique que nous offre Django, on en oublie l'essentiel, je n'utilisais le terminal que comme « journal d'opérations ».

Dans tous les cas, je suis bien arrivé à un résultat convenable.

Merci beaucoup pour votre aide et encore bravo pour Creme.
  Répondre
#8
En complément, je peux vous faire part d'un petit problème d'encodage de caractères.

En voulant créer de nouveaux modèles, certains caractères n'étaient pas bien pris en compte par Latex.

Par exemple, si dans le nom de l'activité on a une apostrophe (Activité d'Anne) et si on veut récupérer ce titre dans un template Latex, il faut encadrer la partie du template en question (ou tout le template) par :
Code :
{% autoescape off %}
    {{ les_variables_pouvant_poser_problème }}
    ...
{% endautoescape %}

Cela évite les problèmes comme les affichages de ce style "Activité d'Anne" sur le PDF et un message d'erreur de Latex.
  Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)