Gaurav Tomer
Gaurav Tomer

Reputation: 731

Adding an extra field in a ModelSerializer is not working

serializers.py:

from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
import models


class ExtensibleModelSerializerOptions(serializers.Serializer):

    def __init__(self, meta):
        super(ExtensibleModelSerializerOptions, self).__init__(meta)
        self.model = getattr(meta, 'model', None)
        self.read_only_fields = getattr(meta, 'read_only_fields', ())
        self.non_native_fields = getattr(meta, 'non_native_fields',())


class ExtensibleModelSerializer(serializers.ModelSerializerOptions):

    _options_class = ExtensibleModelSerializerOptions

    def restore_object(self, attrs, instance=None):

        for field in self.opts.non_native_fields:
            attrs.pop(field)

        return super(ExtensibleModelSerializer, self).restore_object(attrs, instance)

    def to_native(self, obj):

        ret = self._dict_class()
        ret.fields = {}

        for field_name, field in self.fields.items():
            # --- BEGIN EDIT --- #
            if field_name in self.opts.non_native_fields:
                continue
            # --- END --- #
            field.initialize(parent=self, field_name=field_name)
            key = self.get_field_key(field_name)
            value = field.field_to_native(obj, field_name)
            ret[key] = value
            ret.fields[key] = field
        return ret

class OptiUserSerializer(ExtensibleModelSerializer):
    password_confirmation = serializers.CharField(max_length=models.OptiUser._meta.get_field('password').max_length)
    company_id = serializers.PrimaryKeyRelatedField(queryset=models.Company.objects.all(), many=False)
    password = serializers.CharField(
        style={'input_type': 'password'}
        )

    def validate_password_confirmation(self, attrs, source):
        password_confirmation = attrs[source]
        password = attrs['password']

        if password_confirmation != password:
            raise serializers.ValidationError(_('Password confirmation mismatch'))

        return attrs

    class Meta:
        model = models.OptiUser
        fields = ('id', 'username', 'company_id', 'first_name', 'last_name', 'is_active', 'is_admin', 'password', 'password_confirmation',)
        non_native_fields = ('password_confirmation',)

I'm having a customized User model for my app. I'm creating web a web service using DRF. I'm trying to make a user registration serializer as specified above. Everything is working fine except when I add 'password_confirmation' field it raises exception "model_name" object has no attribute password_confirmation". I found a code snippet as above which I'm trying to use above. But unfortunately it doesn't seems to be much helpful.

My question is that, Is it possible to add such a field and perform some comparisons on it. Is there any elegant way to do it?

Please suggest a fix.

Thanks! in Advance.

Upvotes: 0

Views: 745

Answers (1)

JimmyYe
JimmyYe

Reputation: 844

I don't think you need ExtensibleModelSerializer. Set the field to write_only:

password_confirmation = serializers.CharField(write_only=True, ...)

Upvotes: 1

Related Questions