0

J'étudie le CBV dans django. Je veux qu'un utilisateur puisse télécharger des images sur une certaine carte d'un appartement. Ainsi, le modèle a été créé:Django. Obtenir l'identifiant de l'objet ForeignKey dans CreateView

class Photo(models.Model): 
    photo_path = models.ImageField(verbose_name='Фотография') 
    photo_user = models.ForeignKey(User, verbose_name='Агент, добавивший фото') 
    photo_flat = models.ForeignKey(Flat, verbose_name='Квартира') 
    photo_description = models.CharField(verbose_name='Описание', max_length=200, null=True, blank=True) 

Les données initiales du formulaire sont photo_user et photo_flat. Lorsque j'essaie d'enregistrer une ou plusieurs images à travers un formulaire sur la page, j'ai AttributeError.

'NoneType' object has no attribute 'pk' 

Mon ModelForm ressemble à ceci:

class PhotoUploadModelForm(forms.ModelForm): 

    class Meta: 
     model = Photo 
     fields = ['photo_path','photo_user','photo_flat','photo_description' 

Mon CreateView:

class PhotoUploadView(CreateView): 
    form_class = PhotoUploadModelForm 
    def get_initial(self): 
     return {'photo_user': self.request.user, 
       'photo_flat': self.object.pk 
       } 
    def get_success_url(self): 
     return reverse('ha:flatdetail') 

et mon urls.py

url(r'^dev/flat/(?P<flat_id>[0-9]+)/$', views_dev.flat_ajax, name='flatdetail'), 
url(r'^dev/photo-update/$', views_dev.PhotoUploadView.as_view(), name='image-update') 

Je comprends l'erreur, mais n'a pas assez compétences pour le gérer. Ai-je raison de dire que self.object.pk serait l'identifiant de l'image mais pas l'appartement? Puis-je obtenir l'identifiant de l'appartement?

+0

@Pythonista, je pense que j'essaie de faire quelque chose de stupide, Si je veux passer flat.id à 'photo_flat', je devrais peut-être inclure' flat = get_object_or_404 (Flat) 'dans' def get_initial (self) '? Mais il renvoie toute la liste des appartements que j'ai. Comment puis-je transmettre certains ID? Comme ceci: 'flat = get_object_or_404 (Flat, pk = flat_id)'? Mais cela ne fonctionne pas parce que 'get_initial' n'a pas' flat_id' –

Répondre

2

Vous avez mal interprété l'erreur, mais c'est en partie parce que ce que vous faites n'a pas beaucoup de sens.

self.object ne peut faire référence qu'à l'objet concerné par cette vue, en l'occurrence la photo; mais bien sûr cette photo n'existe pas encore quand vous faites get_initial, parce qu'elle n'a pas été créée. Il semble que vous voulez utiliser l'ID d'un objet Flat spécifique; Dans ce cas, vous devrez transmettre cet identifiant à la vue, c'est-à-dire via l'URL. Vous le faites déjà dans votre vue flat_ajax; vous devriez faire exactement la même chose ici, et ensuite vous serez en mesure de référencer l'ID via self.kwargs['flat_id'].

Notez que get_initial n'est pas vraiment le meilleur endroit pour le faire, de toute façon. L'utilisateur et l'objet plat ne sont pas des valeurs que vous souhaitez transmettre au formulaire afin qu'ils remplissent initialement les champs mais permettent à l'utilisateur de les modifier; ce sont des valeurs que vous souhaitez associer automatiquement à l'objet lors de la sauvegarde. Donc, cela devrait vraiment être fait dans form_valid, comme le montre the documentation:

def form_valid(self, form): 
    form.instance.photo_user = self.request.user 
    form.instance.photo_flat_id = self.kwargs['flat_id'] 
    return super(PhotoUploadView, self).form_valid(form) 

Si vous le faites de cette façon, vous devez supprimer photo_user et photo_flat des champs répertoriés sous forme.