nekvs
nekvs

Reputation: 9

How set Foreign key value as email not ID?

I have User Model and Favorite Product Model. I have link as ID to user in Favorite Product model. Can I change ID link to email?

This is my User Model.

class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model that supports using email instead of username"""
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255, default='Фамилия')
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    favorite_product = models.ForeignKey(
        'FavoriteProduct',
        related_name='favorite_products_for_user',
        on_delete=models.SET_NULL, null=True
    )

    objects = UserManager()

    USERNAME_FIELD = 'email'

This is my Favourite Product model

class FavoriteProduct(models.Model):
    """Favorite product object"""
    created = models.DateTimeField(auto_now_add=True, null=True)
    product = models.ForeignKey(
        'Product',
        related_name='favorite_products',
        on_delete=models.CASCADE, null=True
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

favorite_product\serializers.py

from rest_framework import serializers

from core.models import FavoriteProduct


class FavoriteProductSerializer(serializers.ModelSerializer):
    """Serializer for favorite products objects"""

    class Meta:
        model = FavoriteProduct
        fields = ('__all__')
        read_only_fields = ('id',)

user\serializers.py

from django.contrib.auth import get_user_model, authenticate
from django.utils.translation import ugettext_lazy as _

from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
    """Serializer for the users object"""

    class Meta:
        model = get_user_model()
        fields = ('email', 'password', 'name', 'surname')
        extra_kwargs = {'password': {'write_only': True, 'min_length': 5}}

    def create(self, validated_data):
        """Create a new user with encrypted password and return it"""
        return get_user_model().objects.create_user(**validated_data)

    def update(self, instance, validated_data):
        """Update a user, setting the password correctly and return it"""
        password = validated_data.pop('password', None)
        user = super().update(instance, validated_data)

        if password:
            user.set_password(password)
            user.save()

        return user


class AuthTokenSerializer(serializers.Serializer):
    """Serializer for the user authentication object"""
    email = serializers.CharField()
    password = serializers.CharField(
        style={'input_type': 'password'},
        trim_whitespace=False
    )

    def validate(self, attrs):
        """Validate and authenticate the user"""
        email = attrs.get('email')
        password = attrs.get('password')

        user = authenticate(
            request=self.context.get('request'),
            username=email,
            password=password
        )
        if not user:
            msg = _('Аутентификация не прошла по указанным данным')
            raise serializers.ValidationError(msg, code='authentication')

        attrs['user'] = user
        return attrs


class USerializer(serializers.ModelSerializer):
    """Serializer for user objects"""

    class Meta:
        model = get_user_model()
        fields = ('__all__')
        read_only_fields = ('id',)

If you do not understand me? I uploaded picture.png file.enter image description here

Upvotes: 0

Views: 496

Answers (2)

itismoej
itismoej

Reputation: 1847

This has nothing to do with Models. It's about serializing the model objects.

from rest_framework import serializers


class FavoriteProductSerializer(serializers.ModelSerializer):
    user = serializers.RelatedField(source='email', read_only=True)

    class Meta:
        model = FavoriteProduct
        fields = ('id', 'created', 'product', 'user')


Upvotes: 1

from_the_docs
from_the_docs

Reputation: 117

from_the_docs: I think what you need to do is set

USERNAME_FIELD = 'email'

in your User Model.

Also, I would suggest changing name of your Customer User Model to something else like MyUser or CustomerUser to avoid confusion with default User Model provided by django.

Upvotes: 0

Related Questions