django 为什么我测试的页面返回301响应而不是200响应?

2guxujil  于 2023-03-20  发布在  Go
关注(0)|答案(3)|浏览(164)

作为课程的一部分,我正在编写django项目中基于类的视图的测试.目前,我正试图测试一个指向需要用户登录的编辑页面的视图.当然,正在编辑的项目也必须是由该用户首先创建的.
在测试中,我示例化了一个模型和一个用户,然后让用户登录,然后尝试 get 编辑页面。我希望响应的状态代码为200,但它总是返回301。代码如下:

urls.py -编辑页面的路径

path('edit/<slug:slug>/', views.EditBulletin.as_view(), name='edit'),

models.py-正在示例化的模型

class Bulletin(models.Model):
    title = models.CharField(max_length=40, unique=True)
    slug = models.SlugField(max_length=40, unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, 
                               related_name='bulletins')
    content = models.TextField()
    link = models.URLField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
    likes = models.ManyToManyField(User, related_name='bulletin_likes')
    edited = models.BooleanField(default=False)
    updated_on = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

    def number_of_likes(self):
        return self.likes.count()

views.py -编辑页面视图中的get方法

class EditBulletin(View):
    def get(self, request, slug, *args, **kwargs):
        queryset = Bulletin.objects.filter(status=1)
        bulletin = get_object_or_404(queryset, slug=slug, author=request.user)

        bulletin_form = BulletinForm(instance=bulletin)

        return render(
            request,
            'edit_bulletin.html',
            {
                'bulletin_form': bulletin_form,
                'bulletin': bulletin,
                'original_url_query': request.GET.get('query'),
            },
        )

test_views.py -setUpClass方法和编辑页面测试(都在类TestViews(TestCase):中)

@classmethod
def setUpClass(cls):
    cls.user_1 = User.objects.create_user(username='test_user',
                                          password='test')

def test_get_edit_bulletin_page(self):
    bulletin_title = 'New Bulletin'
    title_slug = slugify(bulletin_title)

    self.client.login(username=self.user_1.username,
                      password=self.user_1.password)

    bulletin = Bulletin.objects.create(title=bulletin_title,
                                       slug=title_slug,
                                       author=self.user_1,
                                       content='This is a test bulletin.',
                                       link='https://www.google.ie/',
                                       edited=False)

    response = self.client.get(f'/edit/{bulletin.slug}')

    self.assertEqual(response.status_code, 200)
    self.assertTemplateUsed(response, 'edit_bulletin.html')

我尝试使用self.client.force_login,但它不起作用,但我不确定我是否正确使用了它。
我还尝试在Bulletin对象示例化期间初始化多对多的“喜欢”字段,但没有成功,因为我知道在管理面板中,如果不提供“喜欢”的值,即喜欢过某个Bulletin的用户,我就无法批准该Bulletin。
我很困惑为什么会返回301。我知道如果你输入一个编辑url对应于一个你没有创建的公告,它会显示一个404页面。或者,至少,当DEBUG设置为True时,它会显示一个错误页面。
最后,为了防止这一点还不明显,我应该补充一点,我是一个新手。所以如果有什么非常愚蠢的东西在上面跳出来,请温柔!

qij5mzcb

qij5mzcb1#

创建用户时,通过文本字符串设置密码。但是,在将密码存储到user.password之前,会对其进行散列处理
当您尝试使用user.password(存储的散列密码)登录时,提供的密码将在比较前再次散列。这将失败,并可能导致重定向。
试试看

self.client.login(username=self.user_1.username,
                      password="test")
yvgpqqbh

yvgpqqbh2#

301可能是由于您用来请求编辑页面的URL与您定义的URL模式不完全匹配。
你用字符串插值来构造URL的方法并不是最好的主意,因为这些潜在的错误。尝试使用Django的urls.reverse

# test function start
    bulletin = Bulletin.objects.create(title=bulletin_title,
                                       slug=title_slug,
                                       author=self.user_1,
                                       content='This is a test bulletin.',
                                       link='https://www.google.ie/',
                                       edited=False)
    url = reverse('edit', kwargs={'slug': bulletin.slug})
    # test function assertions etc

这应该总是构造与您在urls.py文件中定义的URL相同的URL,因为在幕后,这个方法实际上获得了与您声明的路径完全相同的路径。

xriantvc

xriantvc3#

urls.py
path('edit/<slug:slug>/', views.EditBulletin.as_view(), name='edit'),

test_views.py
response = self.client.get(f'/edit/{bulletin.slug}')

我相信这就是问题所在。
您将视图url定义为带有斜杠的end,但是当您在test函数中请求url时,您使用的url末尾没有斜杠。
Django用一个301响应,将你重定向到正确的url,**结尾有一个斜线。

相关问题