在Tastypie中,为什么在创建新用户时密码不会写入数据库?

时间:2014-03-29 13:47:21

标签: django tastypie

我正在尝试创建新用户(+他们的个人资料),似乎很好(回复201),但数据库上的密码为空。

我有以下型号:

class CliProfile(models.Model):
    user = models.OneToOneField(User, related_name='cliuser')
    # other stuff

以及以下资源:

class CliProfileResource(ModelResource):

    user = fields.ForeignKey(UserResource, 'user', full=True)

    class Meta(CommonResourceMeta):
        queryset = CliProfile.objects.all()
        resource_name = 'client_infos'
        fields = ['id']
        list_allowed_methods = ['post']


    def obj_create(self, bundle, request=None, **kwargs):
        '''
        We only need the email-adress to register a user. 
        '''

        ema = bundle.data['user']['email']
        usn = ema[:30] # Dirty, will be changed
        raw_pwd = mkpasswd() # Returns a 8 characters random password

        try:
            # Launches model validation
            User(username=usn, email=ema, password=raw_pwd).full_clean()
        except ValidationError as e:
            raise CustomBadRequest(
                code="wrong_user_infos_exception",
                message="Information is wrong as detailed: {0}".
                    format(e))
        else:
            bundle.data['user']['username'] = usn
            bundle.data['user']['password'] = make_password(raw_pwd)
            bundle = super(ClientInfoResource, self).obj_create(bundle, **kwargs)

        return bundle

     # The UserResource is not paste here, but it has nothing special (no override)

POST请求的数据有效负载简单如下:

data_post = {
        "user":{
            "email": "newuser@newuser.com",
        }

另一个问题。我觉得我做错了,因为我认为用户创建应该在UserResource中,而不是在CliProfileResource中。 实际上,我有BusinessProfileResource(也链接到用户),我将不得不在这个资源中放置相同的用户创建,这不是干的。 有没有一种简洁的方法来拆分:在UserResource中创建用户和在CliProfileResource中创建剪贴文信息?

谢谢。

1 个答案:

答案 0 :(得分:0)

我找到了原因,因为我的UserResource的fields字段在允许的字段中不包含password。 当我添加它时,它可以工作。

然而,由于GET请求有密码存在问题,这就是我为什么要覆盖UserResource的dehydrate()方法的原因。

工作版本是:

class Meta(CommonResourceMeta):
    queryset = User.objects.all()
    resource_name = 'users'
    fields = ['id', 'username', 'email', 'password', 'bizuser']
    detail_allowed_methods = ['get']

...

def dehydrate(self, bundle):
    '''Remove pwd from data bundle for obvious security purposes'''
    try:
        bundle.data.pop('password')
    except:
        pass
    return bundle