2010-06-10 10 views
3

dans une mini communauté virtuelle, j'ai une fonction profile_view, de sorte que je peux voir le profil de tout utilisateur enregistré. La fonction d'affichage de profil a comme paramètre l'ID de l'utilisateur wich le profil appartient, de sorte que lorsque je veux accéder au profil de l'utilisateur 2 par exemple, je l'appelle comme ça: http://127.0.0.1:8000/accounts/profile_view/2/django nom d'utilisateur dans l'URL, au lieu de l'ID

Mon problème est que Je voudrais avoir le nom d'utilisateur dans l'URL, et PAS l'identifiant. J'essaie de modifier mon code comme suit, mais cela ne fonctionne pas encore. Voici mon code:

Vue:

def profile_view(request, user): 
     u = User.objects.get(pk=user) 
     up = UserProfile.objects.get(created_by = u) 
     cv = UserProfile.objects.filter(created_by = User.objects.get(pk=user)) 
     blog = New.objects.filter(created_by = u) 
     replies = Reply.objects.filter(reply_to = blog) 
     vote = Vote.objects.filter(voted=blog) 
     following = Relations.objects.filter(initiated_by = u) 
     follower = Relations.objects.filter(follow = u) 
    return render_to_response('profile/publicProfile.html', { 
     'vote': vote, 
     'u':u, 
     'up':up, 
     'cv': cv, 
     'ing': following.order_by('-date_initiated'), 
     'er': follower.order_by('-date_follow'), 
     'list':blog.order_by('-date'), 
     'replies':replies 
     }, 
     context_instance=RequestContext(request)) 

et mon url:

urlpatterns = patterns('', 
         url(r'^profile_view/(?P<user>\d+)/$', 
          profile_view, 
          name='profile_view'), 

merci à l'avance!

Répondre

19

Vous ne montrez pas ce que vous avez essayé, ou où vous rencontrez des problèmes. C'est assez simple, après tout - il suffit de passer une chaîne de nom d'utilisateur à la fonction au lieu d'un entier, et rechercher en fonction de cela.

def profile_view(request, username): 
    u = User.objects.get(username=username) 

et modifier votre URL pour permettre à des chaînes plutôt que des entiers:

url(r'^profile_view/(?P<username>\w+)/$', 
         profile_view, 
         name='profile_view'), 
+10

basé sur ce que je vois dans django/contrib/auth/forms.py Je pense que une meilleure regex à utiliser pour saisir le nom d'utilisateur est (? P [\ w. @ + -] +) –

+0

Que faire si nom d'utilisateur est un e-mail et vous ne voulez pas que cette information soit publique? Vous pouvez utiliser le prénom et le nom de l'utilisateur, mais cela pourrait être dupliqué, donc je pense que nous devrions ajouter un ID ou un hash sur l'ID – jobima

2

Ajouter en haut du fichier:

from django.shortcuts import get_object_or_404 

et remplacer

u = User.objects.get(pk=user) 

avec

u = get_object_or_404(User, <login>=user) 

connexion est le champ de nom d'utilisateur dans le modèle de l'utilisateur.

+0

J'ai remplacé juste comme vous l'avez dit, et il dit que j'ai une erreur de syntaxe à la ligne "u = User.objects.get ( = utilisateur) " – dana

+1

Remplacez le nom de la zone par son nom d'utilisateur, je ne sais pas comment il s'appelle, regardez aussi l'autre réponse et corrigez l'URL –

+0

oui, c'est tout! :) – dana

9

Voici comment je le fais en utilisant des vues génériques à base de classe et l'utilisation des limaces. C'est étonnamment facile et ne nécessite que quelques lignes de code à l'aide de limaces.

# accounts/views.py 
from django.contrib.auth.models import User 
from django.views.generic.detail import DetailView 

class UserProfileView(DetailView): 
    model = User 
    slug_field = "username" 
    template_name = "userprofile.html" 

# accounts/urls.py 
from views import UserProfileView 
urlpatterns = patterns('', 
    # By user ID 
    url(r'^profile/id/(?P<pk>\d+)/$', UserProfileView.as_view()), 
    # By username 
    url(r'^profile/username/(?P<slug>[\[email protected]+-]+)/$', UserProfileView.as_view()), 
) 

Maintenant, vous pouvez accéder à la fois à l'utilisateur comme accounts/profile/id/123/ ainsi que accounts/profile/username/gertvdijk/.

Que se passe-t-il ici?

  • Le paramètre d'URL pk habituellement requis est omis et remplacé par slug dans le modèle d'URL. Ceci est accepté par la vue, car ...
  • Le paramètre slug est utilisé par la vue DetailView (ou toute autre vue SingleObjectMixin) pour trouver l'objet sur User.username en utilisant model = User et slug_field = "username". (docs)
  • Étant donné qu'un champ slug est facultatif, la vue sert également avec bonheur en utilisant uniquement le paramètre pk.
+1

le nom d'utilisateur a l'un des. @ + car ce ne sont pas des caractères valides dans un slug? – rozzy

+0

Comment faites-vous cela dans le cas de l'extension User to UserProfile (vous savez à ge t plus de champs pour un utilisateur). Le modèle User a le champ 'nom d'utilisateur' mais le modèle UserProfile a les champs personnalisés que je veux montrer aussi. – RicardoGonzales

+0

@RicardoGonzales C'est assez simple ... change le 'model' et le' slug_field'. Fonctionne avec tous les modèles Django, cette recette, pas seulement avec 'User's. – gertvdijk