Django - 在测试中获取用户对象 [英] Django - getting user objects in tests

查看:47
本文介绍了Django - 在测试中获取用户对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的models.py:

from django.db 导入模型从 django.contrib.auth.models 导入用户#万物皆有颜色...类颜色(模型.模型):颜色=models.CharField(max_length=100)def __unicode__(self):返回self.color# 东西可以有颜色...类事物(模型.模型):name = models.CharField(max_length=155)颜色 = 模型.外键(颜色)description = models.CharField(max_length=255)def __unicode__(self):返回 self.name# 用户可以保存他的选择类用户喜欢(模型.模型):用户 = 模型.外键(用户)颜色 = 模型.外键(颜色)东西=models.ForeignKey(东西)元类:verbose_name_plural = "用户喜欢"def __unicode__(self):返回 '​​%d - %s' % (self.pk, self.user)

在我看来:

def ThingPicker(请求):如果 request.method == 'POST':form = ThingForm(request.POST)如果 form.is_valid():颜色 = form.cleaned_data['颜色']thing = form.cleaned_data['thing']喜欢 = UserLikes(user=request.user, colour=colour, thing=thing)喜欢.save()return HttpResponseRedirect('/profile/')别的:return render_to_response('thing_picker.html', {'形式':形式,}, RequestContext(request))别的:形式 = ThingForm()return render_to_response('thing_picker.html', {'形式':形式,}, RequestContext(request))

在我的 tests.py 中,我想做这样的事情(已编辑):

class ViewTests(TestCase):定义设置(自我):self.client = Client()def test_thingpicker(self):User.objects.create_superuser('foo', 'myemail@test.com', 'bar')self.client.login(username='foo', password='bar') # request.user 现在是用户 fooresponse = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})userlike = UserLikes.objects.get(pk=1)self.assertEqual(userlike.colour_id, 1)

我收到一个错误:

DoesNotExist:UserLikes 匹配查询不存在.

如果我在 shell 中尝试使用测试客户端:

<预><代码>>>>c = 客户端()>>>user1 = User.objects.create_superuser('foo', 'myemail@test.com', 'bar')>>>c.login(用户名='foo', 密码='bar')>>>c.post('/colours/things/', {'user': user1, 'colour': 1, 'thing': 2})>>>userlike = UserLikes.objects.get(pk=1)>>>userlike.colour_id1L

我得到了预期的结果.

解决方案

您的视图代码有些奇怪(意外剪切和粘贴?),但来自以下代码行:

likes = UserLikes(user=request.user, colour=colour, thing=thing)

我猜您正在获取当前登录的用户.要从测试用例中正确获取新创建的超级用户,您应该这样做:

def test_thingpicker(self):user1 = User.objects.create_user('foo', 'myemail@test.com', 'bar')self.client.login(username='foo', password='bar') # request.user 现在是用户 fooresponse = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})userlike = UserLikes.objects.get(user=user1, color=1, thing=2)

此外,您应该注意 request.user 可能是 AnonymousUser(请参阅 https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AnonymousUser),因此您应该检查用户是否在创建 UserLikes 之前登录.

您可以使用 @login_required 装饰器 (https://docs.djangoproject.com/en/dev/topics/auth/#the-login-required-decorator) 或手动检查 request.user.is_authenticated() (https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AbstractBaseUser.is_anonymous).

为什么没有创建 UserLikes

从观点来看:

colour = form.cleaned_data['colour']thing = form.cleaned_data['thing']喜欢 = UserLikes(user=request.user, colour=colour, thing=thing)

请注意,UserLikes 的模型定义将 ForeignKey 用于颜色和事物.我猜测表单中的 colourthing 是一个 IntegerField,因此您需要检索实际的 Color 和 Thing 对象.

color = Colour.objects.get(pk=form.cleaned_data['colour'])thing = Thing.objects.get(pk=form.cleaned_data['thing'])喜欢 = UserLikes(user=request.user, colour=colour, thing=thing)

当然,您需要确保之前已经创建了 Color 和 Thing 对象.

I have a models.py like so:

from django.db import models
from django.contrib.auth.models import User


# everything has a colour...
class Colour(models.Model):
    colour = models.CharField(max_length=100)

    def __unicode__(self):
        return self.colour


# a thing can have a colour...
class Thing(models.Model):
    name = models.CharField(max_length=155)
    colour = models.ForeignKey(Colour)
    description = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name


# a user can save his choices
class UserLikes(models.Model):
    user = models.ForeignKey(User)
    colour = models.ForeignKey(Colour)
    thing = models.ForeignKey(Thing)

    class Meta:
        verbose_name_plural = "User Likes"

    def __unicode__(self):
        return '%d - %s' % (self.pk, self.user)

And in my views:

def ThingPicker(request):
    if request.method == 'POST':
        form = ThingForm(request.POST)
        if form.is_valid():
            colour = form.cleaned_data['colour']
            thing = form.cleaned_data['thing']
            likes = UserLikes(user=request.user, colour=colour, thing=thing)
            likes.save()
            return HttpResponseRedirect('/profile/')
        else:
            return render_to_response('thing_picker.html', {
                'form': form,
            }, RequestContext(request))
    else:
        form = ThingForm()
        return render_to_response('thing_picker.html', {
            'form': form,
        }, RequestContext(request))

And in my tests.py I want to do something like this (EDITED):

class ViewTests(TestCase):
    def setUp(self):
        self.client = Client()      

    def test_thingpicker(self):
        User.objects.create_superuser('foo', 'myemail@test.com', 'bar')
        self.client.login(username='foo', password='bar') # request.user is now user foo

        response = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})
        userlike = UserLikes.objects.get(pk=1)
        self.assertEqual(userlike.colour_id, 1)

I get an error:

DoesNotExist: UserLikes matching query does not exist.

If I try with the test client in shell:

>>>  c = Client()
>>>  user1 = User.objects.create_superuser('foo', 'myemail@test.com', 'bar')
>>>  c.login(username='foo', password='bar')
>>>  c.post('/colours/things/', {'user': user1, 'colour': 1, 'thing': 2})
>>>  userlike = UserLikes.objects.get(pk=1)
>>>  userlike.colour_id
1L

I get the expected result.

解决方案

There's something weird with your view code (accidental cut and paste?), but from the following line of code:

likes = UserLikes(user=request.user, colour=colour, thing=thing)

I am guessing that you are getting the current logged in user. To correctly get your newly created superuser from your Test case, you should do this:

def test_thingpicker(self):
    user1 = User.objects.create_user('foo', 'myemail@test.com', 'bar')

    self.client.login(username='foo', password='bar') # request.user is now user foo

    response = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})
    userlike = UserLikes.objects.get(user=user1, color=1, thing=2)

In addition, you should note that request.user may be an AnonymousUser (see https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AnonymousUser) and hence you should check whether the user is logged in before creating an UserLikes.

You can do so by using the @login_required decorator (https://docs.djangoproject.com/en/dev/topics/auth/#the-login-required-decorator) or manually checking request.user.is_authenticated() (https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AbstractBaseUser.is_anonymous).

Why UserLikes was not created

From the view:

colour = form.cleaned_data['colour']
thing = form.cleaned_data['thing']
likes = UserLikes(user=request.user, colour=colour, thing=thing)

Note that the Model definition for UserLikes uses ForeignKey for Colour and Thing. I am guessing that colour and thing in the form is an IntegerField, so you need to retrieve the actual Colour and Thing objects.

color = Colour.objects.get(pk=form.cleaned_data['colour'])
thing = Thing.objects.get(pk=form.cleaned_data['thing'])
likes = UserLikes(user=request.user, colour=colour, thing=thing)

Of course, you need to ensure that a Colour and Thing object has been already created before.

这篇关于Django - 在测试中获取用户对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆