2014-04-12 27 views
13

tôi sau this tutorial nhưng phải đối mặt với những vấn đề này tôi không thể sửa chữa:Đăng ký người dùng khung còn lại Django?

  1. Sau khi đăng ký sử dụng, tôi không thể đăng nhập với người dùng đó với các api vì mật khẩu không được băm "định dạng mật khẩu không hợp lệ hoặc chưa biết thuật toán băm. " trong quản trị
  2. tôi không thể đăng lên 'api/tài khoản' hoặc xem mẫu tại các api browseable khi tôi không đăng nhập vào api

Mã của tôi:

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

Trong DRF 3.0, 'write_only_fields = ('password',)' được thay đổi cho 'extra_kwargs = { 'mật khẩu': { 'write_only': True} ,} ' –

+1

Một giải pháp tốt khác: http://stackoverflow.com/questions/27468552/changing-serializer-fields-on-the-fly/#answer-27471503 –

Trả lời

1

Xin lưu ý rằng set_password() KHÔNG lưu đối tượng và vì bạn đã gọi siêu đầu tiên, đối tượng của bạn đã được lưu với mật khẩu thô.

Chỉ cần sử dụng post_save() để lưu mật khẩu.

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

Điều này có thể không hoạt động trong DRF 3.0.2 – wsgeorge

+3

Điều này không làm việc trong DRF 3.x. – Divick

13

Tôi đã thử câu trả lời được chấp nhận trong DRF 3.0.2 và nó không hoạt động. Mật khẩu không bị băm.

Thay vào đó, ghi đè lên các phương pháp tạo trong mô hình serializer bạn

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 

này băm mật khẩu khi bạn tạo một người dùng bằng cách sử dụng khuôn khổ nghỉ ngơi, không post_save

+2

Có thể dễ dàng hơn khi sử dụng 'User.objects.create_user (** validated_data)' để tạo người dùng (với mật khẩu băm) thay vì làm theo hai dòng – aensm

-1

Chúng tôi có thể viết một tín hiệu trong tài khoản để giải quyết điều này.

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


pre_save.connect(create_hash, sender=User) 
2

Tôi đã sử dụng giải pháp wsgeorge 's để xây dựng của riêng tôi. Một đối tượng trống User được tạo ra chỉ để tôi có thể sử dụng .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) 

Khác với câu trả lời của mình, tôi không tiết kiệm cho người dùng bản thân mình. Tôi để điều đó cho lớp cha mẹ gọi số super.

6

Một cách tiếp cận để 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

bạn hoàn hảo –

Các vấn đề liên quan