2012-08-17 5 views
1

je voudrais créer une page « mise à jour le profil de l'utilisateur » pour permettre aux utilisateurs de modifier leurs profils, donc je viens avec les modèles suivants:problèmes Django Form avec UserProfile

class Profile(models.Model): 
    user = models.OneToOneField(User) 

    nick_name = models.CharField(blank=True,max_length=100) 
    school = models.CharField(blank=True,max_length=100) 
    motto = models.CharField(blank=True,max_length=100) 

class ProfileForm(ModelForm): 
    class Meta: 
     model = Profile 

Et mon avis est conçu comme :

@login_required 
def update_profile_view(request): 
    if request.method == 'POST': 
     user = request.user 
     try: 
      profile = user.get_profile() 
     except Exception: 
      profile = Profile.objects.create(user=user) 
     form = ProfileForm(request.POST) 
     if form.is_valid(): 
      cd = form.cleaned_data 
      profile.nick_name = cd['nick_name'] 
      profile.school = cd['school'] 
      profile.motto = cd['motto'] 
      profile.save() 
      return HttpResponseRedirect('/main_page/') 
    else: 
     form = ProfileForm() 
    return render(request, 'update_profile.html', {'form':form}) 

la relation entre un utilisateur et un profil est apparemment 1to1, et à la demande, je peux déterminer l'utilisateur actuel. Le champ utilisateur du formulaire n'a donc pas besoin d'être rempli. Malheureusement, cela n'a pas réussi le test "form.is_valid()". Et il semble difficile de modifier un formulaire avant que "is_valid" ne soit invoqué. Par souci de simplicité, je ne souhaite pas créer ma propre classe de formulaire, et je ne souhaite pas non plus écrire de validation de formulaire personnalisée. Y a-t-il un autre moyen de résoudre le problème?

+0

Quel est le message d'erreur réelle/retraçage? Vous pouvez essayer d'instancier le formulaire avec ProfileForm (request.POST, instance = profile) ... – Jingo

+0

Question très similaire avec des réponses utiles ici: [Django, mise à jour d'un profil utilisateur avec un ModelForm] (http://stackoverflow.com/ questions/1823588/django-update-a-user-profile-avec-un-modelform). – dgel

Répondre

2

Votre vue peut être grandement simplifiée:

@login_required 
def update_profile_view(request): 
    try: 
     profile = Profile.objects.get(user=request.user) 
    except Profile.DoesNotExist: 
     profile = None 

    form = ProfileForm(request.POST or None, instance=profile) 

    if request.method == 'POST':    
     if form.is_valid(): 
      form.save() 
      return HttpResponseRedirect('/main_page/') 
    return render(request, 'update_profile.html', {'form':form}) 

Il n'y a pas besoin d'assigner manuellement les champs comme vous faites. Django ORM sait comment faire un insert par rapport à une mise à jour automatiquement. Donc, si vous passez simplement le ProfileForm une instance d'un profil, il sait faire une mise à jour. S'il n'y a pas d'exemple de profil, il va faire un insert. Maintenant, si vous souhaitez que l'affectation de l'utilisateur soit transparente dans l'interface utilisateur, vous devez exclure le champ user du formulaire et l'affecter vous-même. Il y a plusieurs façons de le faire.

Je vous recommande également d'utiliser reverse dans votre redirection afin de ne pas avoir de chemin codé en dur.

+0

nice, mais, attention, dans la forme de cas GET n'est pas initialisée. Vous devriez déplacer 'form = ...' en première ligne. – danihp

+0

Merci mec. Mon café n'a pas encore commencé. – Brandon

0

Vous pouvez définir la valeur du champ utilisateur comme non obligatoire dans la méthode init (self.fields ['user']. Required = False) du formulaire ou définir l'utilisateur non modifiable dans le modèle (editable = False) .

Dans la méthode vue, profil = appel form.save (commit = False), puis faire profile.user = votre_utilisateur et profile.save()

Vous ne devez pas appliquer les données nettoyées manuellement le profil depuis que ModelForm le fait.

2

Vous avez deux choix: basiquement

1 Modification de ProfileForm:

class ProfileForm(ModelForm): 
     class Meta: 
      model = Profileclass 
      exclude = ('user',) 

2 Modifier ces lignes comme suit:

form = ProfileForm(request.POST, instance=profile) 
if form.is_valid(): 
    updated_profile = form.save()