Django: объект 'UtilisateurUpdateView' не имеет атрибута 'object' - PullRequest
0 голосов
/ 29 мая 2020

Я разрабатываю проект Django с inlineformset, вложенным с использованием FormView.

Сначала я разрабатываю свою форму с помощью CreateView / UpdateView, и она работает, но когда я использую FormView, я получаю ошибку

Объект UtilisateurUpdateView не имеет атрибута object

Почему я могу получить доступ к объекту, когда использую UpdateView, но не с FormView?

Я читал, что это может исходит из метода переопределения, но здесь, похоже, не так?

forms.py

NAME = Thesaurus.options_list(2,'fr')
ACCESS = Thesaurus.options_list(3,'fr') 
ApplicationFormset = inlineformset_factory(
    UtilisateurProjet, Application, #Utilisateur, Application,
    fields=('app_app_nom','app_dro'),
    widgets={
        'app_app_nom': forms.Select(choices=NAME),
        'app_dro': forms.Select(choices=ACCESS)
    },
    extra=3,
    can_delete=True,
)

class UtilisateurProjetUpdateForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(UtilisateurProjetUpdateForm, self).__init__(*args, **kwargs)

        self.fields["pro_ide"] = forms.ModelChoiceField(queryset = PROJETS, label = "Nom projet", widget = forms.HiddenInput(), initial = Projet.objects.get(pro_ide=self.request['projet']))
        self.fields["uti_ide"] = forms.ModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.Select, initial = Utilisateur.objects.get(uti_ide=self.request['utilisateur']))

    class Meta:
        model = UtilisateurProjet
        fields = ('pro_ide','uti_ide',)

views.py

class UtilisateurUpdateView(FormView):
    template_name = 'project/utilisateurprojet_form.html'
    form_class = UtilisateurProjetUpdateForm

    def get_form_kwargs(self):
        kwargs = super(UtilisateurUpdateView, self).get_form_kwargs()
        kwargs['request'] = dict(utilisateur = self.kwargs['pk'], projet = self.kwargs['projet'])
        # kwargs['request'] = self.request
        # print('projet',self.kwargs['projet'])
        # print('utilisateur',self.kwargs['pk'])
        return kwargs

    def get_context_data(self, **kwargs):
        data = super(UtilisateurUpdateView,self).get_context_data(**kwargs)
        # print('projet',self.kwargs['projet'])
        # print('utilisateur',self.kwargs['pk'])
        instance = UtilisateurProjet.objects.get(pro_ide=self.kwargs['projet'],uti_ide=self.kwargs['pk'])
        data['projet'] = Projet.objects.get(pro_ide=self.kwargs['projet'])
        data['utilisateur_app'] = Utilisateur.objects.get(uti_ide=self.kwargs['pk'])
        if self.request.POST:
            data["utilisateur"] = self.request.user.username
            data["user_profil"] = self.request.session.get('user_profil')
            data["application"] = ApplicationFormset(self.request.POST, instance=instance)
        else: 
            data["application"] = ApplicationFormset(instance=instance)
        return data

    def form_valid(self, form):
        # Setting commit to False will return the object without saving it to the Database.
        self.object = form.save(commit=False)
        context = self.get_context_data()
        application = context["application"]
        user_profil = context["user_profil"]
        if user_profil == 'Investigateur':
            self.object.uti_val = 0 # demande modifiée par investigateur -> repasse à non validée + envoie de mail
        elif user_profil == 'Moniteur':
            self.object.uti_val = 1 # demande validée par moniteur -> validée + envoie de mail
            self.object.uti_val_dat = timezone.now()
        else:
            self.object.uti_val = 0
        # After doing our own changes to the object, we can save it.
        self.object.save()

        if application.is_valid():
            # Not sure what is happening here, but this statement does nothing by itself.
            # form.instance = self.object
            application.save()

        return super().form_valid(form)

    def get_success_url(self):
        return reverse("project:index")

1 Ответ

1 голос
/ 29 мая 2020

FormView и DetailView - это разные классы из разных пакетов: django.views.generic.edit.FormView и django.views.generic.detail.DetailView соответственно.

Из документов DetailView :

Хотя это представление выполняется, self.object будет содержать объект, над которым работает представление.

FormView не имеет свойства объекта, потому что он не обязательно работает с объектом.

Однако, поскольку вы используете ModelForms, вы сможете получить доступ к объекту Form после вызова form.save ():

def form_valid(self, form):
        # Setting commit to False will return the object without saving it to the Database.
        self.object = form.save(commit=False)
        context = self.get_context_data()
        application = context["application"]
        user_profil = context["user_profil"]
        self.object.uti_val = 1
        self.object.uti_val_dat = timezone.now()
        else:
            self.object.uti_val = 0
        # After doing our own changes to the object, we can save it.
        self.object.save()

        if application.is_valid():
            # Not sure what is happening here, but this statement does nothing by itself.
            form.instance = self.object
            application.save()

        return super().form_valid(form)
...