2014-04-12 126 views
13

我下面this tutorial但面臨這樣的問題我不能修復:Django rest框架用戶註冊?

  1. 在註冊用戶,我無法與用戶的API登錄,因爲密碼是不是哈希 「無效的密碼格式或未知哈希算法「。在管理
  2. 我不能發表於「API /賬戶」,或看到的形式在瀏覽的API時,我沒有到API登錄

我的代碼:

from django.contrib.auth.models import User 
from rest_framework import serializers 

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('password', 'first_name', 'last_name', 'email') 
     write_only_fields = ('password',) 

    def restore_object(self, attrs, instance=None): 
     # call set_password on user object. Without this 
     # the password will be stored in plain text. 
     user = super(UserSerializer, self).restore_object(attrs, instance) 
     user.set_password(attrs['password']) #somehow not hashing 
     return user 
+1

在DRF 3.0,'write_only_fields =( '密碼',)'被改變爲'extra_kwargs = { '密碼':{ 'WRITE_ONLY':TRUE} ,}' –

+1

另一個很好的解決方案:http://stackoverflow.com/questions/27468552/changing-serializer-fields-on-the-fly/#answer-27471503 –

回答

1

請注意, set_password()不保存對象,並且由於您先調用超級對象,您的對象已經使用原始密碼保存。

只需使用post_save()來保存密碼即可。

def post_save(self, obj, created=False): 
    """ 
    On creation, replace the raw password with a hashed version. 
    """ 
    if created: 
     obj.set_password(obj.password) 
     obj.save() 
+0

這可能不適用於DRF 3.0.2 – wsgeorge

+3

這不在DRF 3.x中工作。 – Divick

13

我試着在DRF 3.0.2中接受的答案,它沒有奏效。密碼未被散列。

相反,覆蓋創建方法模型中的串行

def create(self, validated_data): 
     user = User(email=validated_data['email'], username=validated_data['username']) 
     user.set_password(validated_data['password']) 
     user.save() 
     return user 

當您創建使用REST框架用戶這個散列密碼,而不是post_save

+2

用戶User.objects.create_user(** validated_data)'創建用戶(使用散列密碼)可能更容易,而不是在兩行中完成 – aensm

-1

我們可以寫在用戶的信號來解決這個。

def create_hash(sender, instance=None, *args, **kwargs): 
passwd = instance.password 
instance.set_password(passwd) 


pre_save.connect(create_hash, sender=User) 
2

我已經使用wsgeorge的解決方案來建立我自己的。空白User對象被創建,這樣我可以使用.set_password()

從他的回答
def create(self, validated_data): 
    user = User() 
    user.set_password(validated_data['password']) 
    validated_data['password'] = user.password 
    return super(UserSerializer, self).create(validated_data) 

不同的是,我不保存用戶自己。我把它留給父類,調用super

6

爲DRF 3.X的另一種方法:

from django.contrib.auth import get_user_model 
from django.contrib.auth.hashers import make_password 

    def create(self, validated_data):  
     if validated_data.get('password'): 
      validated_data['password'] = make_password(
       validated_data['password'] 
      ) 

     user = get_user_model().objects.create(**validated_data) 

     return user 
+0

你是完美的 –