dszczyt / django-nested-forms

Nested forms for your django projects
Other
27 stars 5 forks source link

formulaires imbriqués et relation avec une table through #1

Open frague59 opened 13 years ago

frague59 commented 13 years ago

Bonjour,

Ton boulot sur les nested_forms est très inintéressant, mais...

J'ai un petit soucis avec, je t'explique :

Voici mes modèles : code: class FournitureArticle(models.Model): ''' Articles de fournitures ''' class Meta: ordering = ('label',) verbose_name = u'Article de fourniture' verbose_name_plural = u'Articles de fourniture'

label = models.CharField(name='label',
                         verbose_name=u"Libellé",
                         max_length=256,)

def __unicode__(self):
    return self.label

class FournitureDemande(Demande): ''' Demande de fourniture d'articles ''' class Meta: verbose_name = u'Demande de fourniture' verbose_name_plural = u'Demandes de fourniture' permissions = (('directeur_view_fournituredemande', 'DIR - Voir les demandes de fournitures'), ('directeur_add_fournituredemande', 'DIR - Ajouter une demande de fournitures'), ('directeur_change_fournituredemande', 'DIR - Modifier une demande fournitures'), ('gest_valid_fournituredemande', 'GEST - Valider une demande de fournitures'),)

articles = models.ManyToManyField(FournitureArticle,
                                  name='articles',
                                  verbose_name=u'articles',
                                  through='FournitureArticleDemande',
                                  related_name='fourniturearticle_fournituredemande',)
def __unicode__(self):
    return 'Demande de fournitures du %s' % (self.date.strftime('%d %M %Y'))

class FournitureArticleDemande(models.Model): ''' Table de relation entre les demandes de fournitures et les articles. '''

demande = models.ForeignKey('FournitureDemande',
                            name='fourniture_demande', verbose_name=u'Demande',
                            related_name='fourniture_demande_fourniturearticledemande',)

article = models.ForeignKey('FournitureArticle',
                            name='fourniture_article', verbose_name=u'Article',
                            related_name='fourniture_article_fourniturearticledemande',)

quantite = models.IntegerField(name='quantite', verbose_name=u'Quantité',
                               default=0,)

def __unicode__(self):
    return '%s : %s pièce(s)' % (self.article, self.quantite)

Je souhaite faire un formlaire, mais en utilisant le modèle défini dans le 'through' : FournitureArticleDemande comme formulaire 'nested', c'est à dire qu'à l'affichage j'ai un choix d'articles et une quantité saisir.

Pour le moment, j'ai la possibilité d'ajouter une ligne dans la table des articles. Voici le code de mes formulaires : code: def get_choice_article(demande): class FournitureArticleDemandeForm(forms.ModelForm): class Meta: model = models.FournitureArticleDemande fields = ('article', 'quantite',) exclude = ('demande',)

    def save(self, commit=True):
        instance = super(FournitureArticleDemandeForm, self).save(commit=False)
        instance.demande = demande
        logger.debug('FournitureArticleDemandeForm::save() instance = %s' % (instance))
        logger.debug('FournitureArticleDemandeForm::save() demande = %s' % (demande))
        if commit:
            instance.save()
            self.save_m2m()
        return instance

return FournitureArticleDemandeForm

class FournitureDemandeArticlesForm(nested_forms.ThroughComplexModelForm): class Meta: model = models.FournitureDemande fieldsets = widgets = dict(DEMANDE_READONLY_WIDGETS) exclude = ('articles', 'date_reponse', 'statut', 'motif',)

formsets = {'articles': {'form': lambda instance: get_choice_article(instance), 'extra': 1, 'initial':[{'quantite': 0, }], }}

(les lignes sont décalées à droite à l'affichage ^^, mais elles sont bien indentées dans la vraie vie ;) ) Je développe sur django 1.3.x, et j'use et abuse des 'class-based generic views' (qui sont vachement cool si tu connais pas..)

Merci d'avance !

frague

frague59 commented 13 years ago

ps : je suis villeneuvois aussi...

dszczyt commented 13 years ago

Bonjour,

Je suppose que tu voulais dire "intéressant", sinon, tu ne m'enverrais pas ce mail, et donc je te remercie pour ton intérêt et surtout pour ton retour d'expérience. J'ai eu exactement le même problème que toi. Mais après réflexion, notre projet a évolué, et du coup je n'ai pas approfondi la chose plus que ça. A priori, tu as travaillé une classe ThroughComplexModelForm. Qu'a-t-elle de différent avec ma version ? Ce que je te conseillerais, c'est de faire 1 nested form de FournitureDemande vers FournitureArticleDemande, puis un autre nested form de FournitureArticleDemande vers FournitureArticle. Et c'est là le problème : je n'ai pas développé la possibilité d'intégrer un formulaire pour stocker les informations d'une foreignkey, alors que ça serait bien utile. La raison pour laquelle je pense qu'il faut que tu fasses comme cela est la suivante : un ModelForm prend en paramètre Meta un Model. Une relation m2m avec through utilise 2 modèles, ce qui est problématique pour l'alimentation des informations dans la table intermédiaire. C'est pour ça que nous l'avons banni de nos projets. Ceci dit, d'ordre général, attention aux formsets de django : en cas de modification manuelle des données du management form peut entraîner des exceptions, en particulier avec les vues génériques, versions procédurale ou à base de classe (que j'utilise intensivement tous les jours), car celles-ci n'interceptent pas les bonnes exceptions. Et surtout, on ne sait pas quoi faire de ces exceptions. J'ai même été regardé du côté de Ruby On Rails 3 où les nested forms sont directement compris dans le projet... A mon avis c'est tout l système de formulaires qu'il faut revoir chez django ! J'espère avoir répondu à tes questions. N'hésite pas à me retourner ton expérience sur ce projet, je suis prêt à l'adapter pour le rendre plus fiable. La gestion de formulaire est un élément crucial dans mes projets, et toute suggestion est bonne à prendre.

Damien