Django-fr

Forum

#1 26-05-2015 08:52:36

mohamed
Membre
Inscription : 26-05-2015
Messages : 5

Problème de vues générique avec un formset

Bonjour actuellement débutant sur Django je rencontre un problème avec ma vue générique UpdateView. J'utilise actuellement la version 1.9 de Django donc la dernière version de python la 3.4

Voici le models.py:

from django.db import models


class Adresse(models.Model):
    id_adr = models.AutoField(primary_key=True)
    st_adr_adr = models.CharField(max_length=60, blank=True, null=True)
    st_adrl2_adr = models.CharField(max_length=60, blank=True, null=True)
    st_cp_adr = models.CharField(max_length=5, blank=True, null=True)
    st_ville_adr = models.CharField(max_length=40, blank=True, null=True)
    tiers = models.ForeignKey('Tiers', blank=True, null=True)

    def __str__(self):
        return '%s %s %s %s' %(self.st_adr_adr, self.st_adrl2_adr, self.st_cp_adr, self.st_ville_adr)

    class Meta:
        managed = True
        db_table = 'adresse'

class Civilite(models.Model):
    id_civ = models.AutoField(primary_key=True)
    st_lbl_civ = models.CharField(max_length=100, blank=True, null=True)
    st_lbc_civ = models.CharField(max_length=30, blank=True, null=True)
    st_lbcour_civ = models.CharField(max_length=100, blank=True, null=True)
    nm_oldid_civ = models.IntegerField(blank=True, null=True)
    bl_feminin_civ = models.BooleanField()
    bl_pluriel_civ = models.BooleanField()
    id_civ_trs = models.IntegerField(blank=True, null=True)

    def __str__(self):
        return self.st_lbc_civ

    class Meta:
        managed = True
        db_table = 'civilite'




class FormeSociale(models.Model):
    id_tfs = models.AutoField(primary_key=True)
    st_lbc_tfs = models.CharField(max_length=20, blank=True, null=True)
    st_lbl_tfs = models.CharField(max_length=120, blank=True, null=True)
    st_cdinsee_tfs = models.CharField(max_length=4)
    bl_feminin_tfs = models.BooleanField()
    bl_pluriel_tfs = models.BooleanField()
    id_tfs_trs = models.IntegerField(blank=True, null=True)

    def __str__(self):
        return self.st_lbc_tfs
   
    class Meta:
        managed = True
        db_table = 'forme_sociale'


class Tiers(models.Model):
    id_trs = models.AutoField(primary_key=True)
    st_nom_trs = models.CharField(max_length=60, blank=True, null=True)
    st_prenom_trs = models.CharField(max_length=40, blank=True, null=True)
    st_rsoc_trs = models.CharField(max_length=60, blank=True, null=True)
    id_civ = models.ForeignKey(Civilite, db_column='id_civ', blank=True, null=True)
    id_tfs = models.ForeignKey(FormeSociale, db_column='id_tfs', blank=True, null=True)
    id_ttr = models.ForeignKey('TypeTiers', db_column='id_ttr', blank=True, null=True)

    def __str__(self):
        return '%s %s %s' %(self.st_nom_trs, self.st_prenom_trs, self.st_rsoc_trs)
   
    class Meta:
        managed = True
        db_table = 'tiers'


class TypeTiers(models.Model):
    id_ttr = models.AutoField(primary_key=True)
    st_lbl_ttr = models.CharField(max_length=50, blank=True, null=True)
    st_lblsaa_ttr = models.CharField(max_length=50)
    bl_socaf_ttr = models.BooleanField()
    bl_saa_ttr = models.BooleanField()
    id_ttr_trs = models.IntegerField(blank=True, null=True)

    def __str__(self):
        return self.st_lbl_ttr

    class Meta:
        managed = True
        db_table = 'type_tiers'


class LettreRecommandee(models.Model):
    id_rec = models.AutoField(primary_key=True)
    d_envoi_rec = models.DateField(blank=True, null=True)
    st_ref_rec = models.CharField(max_length=60, blank=True, null=True)
    st_type_rec = models.CharField(max_length=60, blank=True, null=True)
    st_num_rec = models.CharField(max_length=60, blank=True, null=True)
    id_exp_trs = models.ForeignKey('Tiers', related_name='id_expe_trs', blank=True, null=True)
    id_des_trs = models.ForeignKey('Tiers', related_name='id_desti_trs', blank=True, null=True)

    def __str__(self):
        return self.st_ref_rec
   
    class Meta:
        managed = True
        db_table = 'lettre_recommandee'


forms.py:

from django import forms
from ex_projet.models import Tiers, Adresse, FormeSociale, Civilite, TypeTiers, LettreRecommandee
from django.forms.models import inlineformset_factory

class TiersForm(forms.ModelForm):

   
    class Meta:
        model = Tiers
        fields = ['st_rsoc_trs','st_nom_trs','st_prenom_trs']


class LettreRecommandeeForm(forms.ModelForm):

    class Meta:
        model = LettreRecommandee
        fields = ['st_ref_rec', 'st_num_rec', 'st_type_rec',]
       

   
AdresseFormSet = inlineformset_factory(Tiers, Adresse, fields = ['st_adr_adr','st_adrl2_adr','st_cp_adr','st_ville_adr'],can_delete=False,extra=1)


views.py:

from django.shortcuts import render, get_object_or_404, render_to_response
from io import BytesIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from ex_projet.models import LettreRecommandee, Tiers, Adresse
from ex_projet.forms import LettreRecommandeeForm, TiersForm, AdresseFormSet
from django.template import RequestContext
from django.forms.models import inlineformset_factory

def accueil(request):
    lettres = LettreRecommandee.objects.all()
    lettres = LettreRecommandee.objects.order_by('id_rec')

    tiers = Tiers.objects.all()
    tiers = Tiers.objects.order_by('id_trs')
   
    return render(request, 'ex_projet/accueil.html', {'derniers_recommandees' : lettres, 'derniers_tiers' : tiers}, context_instance=RequestContext(request))
 


class TiersCreate(CreateView):
    form_class = TiersForm
    model = Tiers
    template_name= 'ex_projet/nouveau.html'
    success_url = reverse_lazy(accueil)



               
    def get(self, request, *args, **kwargs):
       
       
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        adresse_form = AdresseFormSet()
        return self.render_to_response(self.get_context_data(form=form, adresse_form=adresse_form))

    def post(self, request, *args, **kwargs):

        self.object = self.model()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        adresse_form = AdresseFormSet(self.request.POST)

        if form.is_valid() and adresse_form.is_valid():
            return self.form_valid(form, adresse_form)
        else:
            return self.form_invalid(form, adresse_form)

    def form_valid(self, form, adresse_form):
        self.object = form.save()
        adresse_form.instance = self.object
        adresse_form.save()
        return HttpResponseRedirect (self.get_success_url())

    def form_invalid(self, form, adresse_form):

        return self.render_to_response(self.get_context_data(form=form, adresse_form=adresse_form))
       
       
class TiersUpdate(UpdateView):
    form_class = TiersForm
    model = Tiers
    template_name= 'ex_projet/nouveau.html'
    success_url = reverse_lazy(accueil)

    def get_context_data(self, **kwargs):
        context = super(TiersUpdate, self).get_context_data(**kwargs)
        if self.request.POST:
            context['adresse_form'] = AdresseFormSet(self.request.POST, instance=self.object)
         
        else:
            context['adresse_form'] = AdresseFormSet(instance=self.object)
           
        return context


        self.object = self.model()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
       

        if form.is_valid() and adresse_form.is_valid():
            self.object = form.save()
            adresse_form.instance = self.object
            adresse_form.save()
            return HttpResponseRedirect(self.get_success_url())
        else:
            return self.render_to_response(self.get_context_data(form=form, adresse_form=adresse_form))
   
         
   
class TiersDelete(DeleteView):
    model = Tiers
    template_name= 'ex_projet/supprimer.html'
    form_class = TiersForm
    success_url = reverse_lazy(accueil)
   
et mon template :

<html lang="fr-fr">

<h1>Ajout ou Edition d'une Lettre Recommandee </h1>
<link rel="stylesheet" type="text/css" href="/static/admin/css/base.css" />
<link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css" />


<form action="" method="POST">
{% csrf_token %}
{{form.as_ul}}
{{adresse_form.management_form }}
{{adresse_form.non_form_errors }}
{% for form in adresse_form %} 
    <br />             
    {{form.as_table}}
{% endfor %}
<input type="submit" value="Envoyer"/>
</form>

<p><a href="{% url "url_accueil"  %}">Retour à l'accueil</a><p>

Le problème que je rencontre actuellement est qu'une fois que je fais mes modifications il modifie bien mon objet Tiers, mais il ne modifie pas mon objet Adresse car je pense que je rencontre un problème de save pourtant j'ai fait tout ce qu'il fallait pour l'enregistrer sachant que Django me sort aucune erreur !
Merci de votre aide big_smile

Hors ligne

#2 27-05-2015 10:18:16

Xavier Ordoquy
Administrateur
Lieu : Puteaux, France
Inscription : 12-10-2011
Messages : 312
Site Web

Re : Problème de vues générique avec un formset

J'ai des doutes sur la façon d'ajouter l'instance au formeset. Normalement, c'est passé au constructeur il me semble et pas donné à la volée.

Hors ligne

#3 27-05-2015 11:16:03

mohamed
Membre
Inscription : 26-05-2015
Messages : 5

Re : Problème de vues générique avec un formset

Merci pour votre réponse mais je n'ai pas très bien compris où vous voulez en venir. Je me suis inspiré d'un lien qui est le suivant :

http://stackoverflow.com/questions/4497 … or-formset

Et j'ai oublié de mentionné qu'une fois que je déploie et que je vais sur l'UpdateView je récupère bien mon objet Tiers et mon objet Adresse mais en dessous de mes champs adresse sur le site j'ai encore un objet Adresse avec ses champs vides comme si il avait été dupliqué et quand j'essaie de faire mon submit il me sort une erreur en rouge en disant que :

(champ masqué tiers) La clé étrangère en ligne ne correspond pas à clé primaire de l'instance parente.

Merci de votre aide big_smile

Hors ligne

#4 28-05-2015 13:23:50

mohamed
Membre
Inscription : 26-05-2015
Messages : 5

Re : Problème de vues générique avec un formset

c'est bon c'est résolu grâce à un de mes oncles xD en faite il faut que dans le UpdateView lui préciser que l'ID primary key de mon tiers que je veux récupérer correspond bien à celle ma foreignkey de mon adresse sinon il ne sera pas que la foreignkey qui sera affiché sur le web correspondra à l'id_trs puis rajouter cet id dans le context
class TiersUpdate(UpdateView):
 
    form_class = TiersForm
    model = Tiers
    template_name= 'ex_projet/nouveau.html'
    success_url = reverse_lazy(accueil)

    def get_context_data(self, **kwargs):
        # pdb.set_trace()
        context = super(TiersUpdate, self).get_context_data(**kwargs)
 
        if self.request.POST:
            context['adresse_form'] = AdresseFormSet(self.request.POST, instance=self.object)
         
        else:
            adresse = Adresse.objects.filter(tiers_id=self.object.id_trs)[0]
            context['adresse']=adresse
            context['adresse_form'] = AdresseFormSet(instance=self.object)

           
        return context

Je vous remercie d'avance d'avoir essayé de m'aider big_smile

Dernière modification par mohamed (28-05-2015 13:24:20)

Hors ligne

Pied de page des forums