Django имя пользователя в URL, а не ID
В мини-виртуальном сообществе у меня есть функция profile_view, так что я могу просматривать профиль любого зарегистрированного пользователя. Функция просмотра профиля имеет в качестве параметра идентификатор пользователя, которому принадлежит профиль, поэтому, когда я хочу получить доступ к профилю пользователя 2, например, я называю его так: http://127.0.0.1:8000/accounts/profile_view/2/
Моя проблема в том, что я хотел бы иметь имя пользователя в URL, а не идентификатор. Я пытаюсь изменить свой код следующим образом, но он все еще не работает. Вот мой код:
Посмотреть:
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))
и мой URL:
urlpatterns = patterns('',
url(r'^profile_view/(?P<user>\d+)/$',
profile_view,
name='profile_view'),
заранее спасибо!
4 ответа
Вы не показываете, что вы пытались или где у вас возникли проблемы. В конце концов, это довольно просто - просто передайте строку имени пользователя в функцию вместо целого числа и посмотрите на основании этого.
def profile_view(request, username):
u = User.objects.get(username=username)
и измените ваш URL, чтобы разрешить строки, а не целые числа:
url(r'^profile_view/(?P<username>\w+)/$',
profile_view,
name='profile_view'),
Вот как я это делаю, используя основанные на классах общие представления и использование слагов. Это на удивление легко и требует всего несколько строк кода с помощью слагов.
# 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>[\w.@+-]+)/$', UserProfileView.as_view()),
)
Теперь вы можете получить доступ как к пользователю accounts/profile/id/123/
так же как accounts/profile/username/gertvdijk/
,
Что тут происходит?
- Обычно требуется
pk
Параметр URL опущен и заменен наslug
в шаблоне URL. Это принято мнение, потому что... - Параметр slug используется DetailView (или любым другим представлением на основе SingleObjectMixin), чтобы найти объект на
User.username
с помощьюmodel = User
а такжеslug_field = "username"
, ( документы) - Поскольку поле slug является необязательным, представление также успешно работает, используя только
pk
параметр.
В urls.py
urlpatterns = [
path('<str:username>/', UserDetailView.as_view(), name='user_detail'),
]
С классовым представлением.
class UserDetailView(LoginRequiredMixin, DetailView):
model = User
slug_field = "username"
slug_url_kwarg = "username"
template_name = "account/user_detail.html"
def get_object(self):
object = get_object_or_404(User, username=self.kwargs.get("username"))
# only owner can view his page
if self.request.user.username == object.username:
return object
else:
# redirect to 404 page
print("you are not the owner!!")
Я тестировал в Django 2.1.
Добавьте в начало файла:
from django.shortcuts import get_object_or_404
и заменить
u = User.objects.get(pk=user)
с
u = get_object_or_404(User, <login>=user)
где логин - это поле имени пользователя в модели пользователя.
Для Django 2.0 и выше:
path(‘profile/<username>/, views.profile, name=‘profile’),