我想在views.py中编写逻辑并在序列化程序中保存数据

时间:2018-03-27 03:59:44

标签: python django

我正在将系统保存的用户数据保存到模型中。我想在views.py中编写一部分逻辑,并在serializer中编写一部分保存数据。我想将系统密码更改为hash.Now我写的views.py中的代码,

class InfoViews(viewsets.ModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer
    lookup_field = 'id'

    def create(self,request, *args, **kwargs):
        user = Info()
        passwd = request.data['password']

        md5 = hashlib.md5()
        md5.update(passwd.encode('utf-8'))

        user.password = md5.hexdigest()

        user.save()
        return JsonResponse({"data":"data"})

在serializer.py

class InfoSerializer(serializers.ModelSerializer):
    created_time = serializers.DateTimeField(required=False)

    class Meta:
        model = Info
        fields = '__all__'

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

在models.py

class Info(models.Model):
    username = custom_fields.NotEmptyCharField(max_length=100, unique=True)
    email = models.EmailField()
    password = custom_fields.NotEmptyCharField(max_length=100)

    class Meta:
        db_table = 'info'

    def __str__(self):
        return '%s: %s' % (self.username, self.email)

现在当我试图将用户数据保存到模型时,django.core.exceptions.ValidationError:['不能为空!']错误发生。我的代码出了什么问题?我搜索http://www.django-rest-framework.org/api-guide/serializers/。怎么办?我解决了这个问题?

2 个答案:

答案 0 :(得分:1)

您收到验证错误,因为email是必填字段。当您运行user.save()时,不会发送email值,因此会发送ValidationError

你绝对应该保存视图中的所有内容,而Serialiser只是一种改变DRF数据呈现方式的方法。

另外,你真的不应该使用md5来保存你的密码。只需使用内置的Django方法:user.set_password(password) - Django将为您提供更安全的哈希处理。

答案 1 :(得分:1)

您没有使用InfoSerializer()序列化程序,因此,从中删除create()方法,然后按照以下方式更改views.py

class InfoViews(ModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer
    lookup_field = 'id'

    def create(self, request, *args, **kwargs):
        serializer = InfoSerializer(request.data).data
        serializer.pop('created_time', None)
        passwd = serializer['password']
        md5 = hashlib.md5()
        md5.update(passwd.encode('utf-8'))
        serializer['password'] = md5.hexdigest()
        Info.objects.create(**serializer)
        return JsonResponse({"data": "data"})



我的友好建议
我不认为这是一个很好的方法来实现,所以下面的改变会做得更好(我想是这样);)

views.py

class InfoViews(ModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer
    lookup_field = 'id'


serializer.py

import hashlib


class InfoSerializer(serializers.ModelSerializer):
    created_time = serializers.DateTimeField(required=False)

    def set_password(self, raw_pwd):
        md5 = hashlib.md5()
        md5.update(raw_pwd.encode('utf-8'))
        return md5.hexdigest()

    class Meta:
        model = Info
        fields = '__all__'

    def create(self, validated_data):
        validated_data['password'] = self.set_password(validated_data['password'])
        return super().create(validated_data)


更新
序列化程序的替代create()

def create(self, validated_data):
    validated_data['password'] = self.set_password(validated_data['password'])
    user = Info.objects.create(
        email=validated_data['email'],
        username=validated_data['username'],
        password=validated_data['password']
    )
    # you can avoid large number of assignment statements (as above) by simply calling "super()" method

    return user