Python 将Django内置登录视图重定向到URL用户';s pk作为参数

Python 将Django内置登录视图重定向到URL用户';s pk作为参数,python,django,Python,Django,在使用Django的内置登录视图成功登录后,我试图重定向到一个以用户pk为参数的URL 我的login.html中没有动态{{next}}变量,而是有一个登录用户的通用登录视图 <input type="submit" value="login" /> <input type="hidden" name="next" value="{% url 'userredirect' %}" /> 我在这里做的是重定向到一个详细视图,在成功登录后,我使用2个重定向在用户模型上命名

在使用Django的内置登录视图成功登录后,我试图重定向到一个以用户pk为参数的URL

我的login.html中没有动态{{next}}变量,而是有一个登录用户的通用登录视图

<input type="submit" value="login" />
<input type="hidden" name="next" value="{% url 'userredirect' %}" />
我在这里做的是重定向到一个详细视图,在成功登录后,我使用2个重定向在用户模型上命名为
UserHome
,因为我不知道直接重定向到
UserHome
的方法(它以用户的pk为参数)。它可以工作,当我通过浏览器检查时,我确实会被重定向到用户的主页

参考文献

但是当运行下面的测试时

    def test_page_redirects_to_user_home_on_login(self):
    """
    Test to assure that the login page redirects to the user's
    home page
    """
    username = "someusername"
    password = "somepassword"
    user = User.objects.create_user(username=username,
                password=password)
    user.save()
    response = self.client.post(reverse("userlogin"),
                                {"username":username,
                                 "password":password},
                                follow=True)
    assert response.path == self.client.get(reverse("userhome", 
                                                    kwargs={"pk":user.id}
                                               )
                                       )
我得到下面的失败

AttributeError: 'HttpResponseNotFound' object has no attribute 'path'
测试客户端似乎没有页面。是否我只是使用
userredirect
视图进行重定向,而客户机不继续将
UserHome
类视图放到其上下文中

我是Django/Python的新手。请有人帮我整理一下:)


我期待着一种方法,可以直接从
login
视图的模板重定向到
UserHome
,或者一种重写我的测试的方法。

如果你的项目没有更多的洞察力,很难说。这里有一些可能性等等

响应没有路径
响应
确实没有
路径
,您可能想要这样:

assert response.wsgi_request.path == reverse("userhome", kwargs={"pk":user.id})
在测试中包括
next
您正在模拟登录表单中的数据,但忽略了
next
字段。 将其添加到发布的数据中:

{"username":username,
"password":password,
"next": '/users/',}
看一看反应是什么 查看测试中的响应可能会有所帮助。例如:

print(response.redirect_chain)
也许你还没到登录页面? 您的
设置.py
中是否缺少
登录\u URL

LOGIN_URL = '/login/'
没有它,您将被重定向到“/accounts/login/”,这可能是您看到的404


最后——为什么?:) 也许您有一些特殊的用例,但我通常会从
request.user
中读取用户的
id
(也称为
pk
)。这样我(例如)就无法访问
example.com/
和访问您的主页。当然,这可能正是你想要的。在这种情况下,我仍然会为当前用户提供一个单独的URL,以后可能会有回报。大概是这样的:

    ...
    url(r'^/', UserHome.as_view(), name='userhome'),
    url(r'^(?P<pk>\d+)/', UserHome.as_view(), name='userhome'),
    ...)



class UserHome(DetailView):  # also protect with some LoginRequiredMixin
    model = User

    def get_object(self, queryset=None):
        if queryset is None:
            queryset = self.get_queryset()
        id = self.kwargs.get('pk', self.request.user.id)
        return queryset.filter(id=id).get()
。。。
url(r'^/',UserHome.as_view(),name='UserHome'),
url(r'^(?P\d+/),UserHome.as_view(),name='UserHome'),
...)
类UserHome(DetailView):#还使用一些LoginRequiredMixin进行保护
模型=用户
def get_对象(self,queryset=None):
如果queryset为无:
queryset=self.get_queryset()
id=self.kwargs.get('pk',self.request.user.id)
返回queryset.filter(id=id).get()

第一件事:您得到的错误是因为

response = self.client.post(reverse("userlogin"),
                                {"username":username,
                                 "password":password},
                                follow=True)
引发404错误,因此响应为
HttpResponseNotFound
。 在测试任何其他内容之前,首先测试您的请求是否成功是一种良好的做法。大致如下:

self.assertEqual(response.status_code, 200)
此外,您正在对url进行硬编码,这与DRY背道而驰,并且常常是麻烦的来源(这里可能就是这种情况)。 最好将所有URL命名为:

url(r'^users/', views.users, name='user_redirect'),
然后在模板中使用它

<input type="hidden" name="next" value="{% url 'user_redirect' %}" />
最后,您在重定向方面采取了不必要的步骤。假设
UserHome
User
上的
DetailView
,您可以拥有以下代码:

##urls.py
url(r'^users/', UserHome.as_view(), name='userhome')

##views.py
from django.views.generic import DetailView
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User


class UserHome(DetailView):
    model = User

    def get_object(self, queryset=None):
        return self.request.user

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(UserHome, self).disatch(*args, **kwargs)
这还将确保没有用户访问其他用户的“用户主页”


这样做可以帮助您找到代码中的错误。祝你好运

您的url.py中是否有登录url的条目?pk是GET的一部分还是不可见?喜欢使用社交媒体查看个人资料吗?问题似乎在于您的
响应
对象没有
路径
属性。也许断言重定向的正确方法是:你抢先到了;-)但我认为
self.kwargs.get(pk=self.request.user.id)
实际上应该是
self.model.objects..get(pk=self.request.user.id)
@Emma-true,没有测试,现在已经改变了。很多frnhr
assert-response.wsgi\u-request.path==reverse(“userhome”,kwargs={“pk”:user.id})
是我真正想要的:)。现在测试通过了。原谅我,我是全新的:)。又来了@如果这个或另一个答案已经解决了你的问题,请考虑通过点击复选标记()来接受它,这向更广泛的社区表明你已经找到了解决方案并给回答者和你自己带来了一些声誉。没有义务这样做。是这样做的:)是不是阿瓦雷玛非常感谢你的时间。多亏了你,我现在已经在这里干了。但问题是我的意图在这里起作用。当通过浏览器进行检查时,我确实会被重定向到用户主页,这确实是用户模型的详细视图。但是在我上面的测试中,客户端似乎找不到任何页面(是否与2个重定向有关?)。我需要知道的是为什么会这样。我之所以在这里使用2个重定向,是因为我不知道如何重定向到我的
userhome
,它将用户的pk作为参数。最好的办法是你能告诉我一个方法:)我对Python/Django非常陌生(这是我的第一个项目,主要是为了学习,而不是工作:))因此,我不明白您在回答末尾的代码中试图传达什么。我回答末尾的代码是一个视图,它呈现当前登录用户的详细视图,要求用户登录而无需提供用户pk。重写的“get_object”方法()从会话中检索用户,而不是通常的行为。通过使用此代码,您可以摆脱
用户
视图。这将使事情更直接,更容易调试。您的问题的最终答案可能在完整堆栈跟踪中。我已经找到了
<input type="hidden" name="next" value="{% url 'user_redirect' %}" />
from django.core.urlresolvers import reverse
@login_required
def users(request):
    url = reverse('userhome', kwargs={'pk': request.user.id})
    return HttpResponseRedirect(url)
##urls.py
url(r'^users/', UserHome.as_view(), name='userhome')

##views.py
from django.views.generic import DetailView
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User


class UserHome(DetailView):
    model = User

    def get_object(self, queryset=None):
        return self.request.user

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(UserHome, self).disatch(*args, **kwargs)