Я пытаюсь соединить модель своих продуктов и пользовательскую модель пользователя, чтобы можно было фильтровать загруженные пользователями продукты. Я не могу понять, как передать зарегистрированного пользователя в форму загрузки.
Когда я вынимаю сериализатор пользователя в сериализаторе продуктов, загрузка не работает, потому что поле пользователя пусто. С пользовательским сериализатором, почтовый запрос странным образом сочетается с регистрационным запросом регистрации. Я не могу найти способ решить эту проблему. Любая помощь будет оценена.
Product models.py
from django.db import models
from django.contrib.auth import get_user_model
# Create your models here.
User = get_user_model()
class Product(models.Model):
objects = models.Manager()
user = models.ForeignKey(User, on_delete = models.CASCADE)
title = models.CharField(max_length = 120)
content = models.TextField()
price = models.IntegerField()
def __str__(self):
return self.title
Product views.py
from products.models import Product
from .serializers import ProductSerializer
from rest_framework import generics
from allswap import settings
class ProductListView(generics.ListCreateAPIView):
"""
A viewset for viewing and editing user instances.
"""
serializer_class = ProductSerializer
queryset = Product.objects.all()
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class userProductListView(generics.ListAPIView):
serializer_class = ProductSerializer
def get_queryset(self):
user = self.kwargs['email']
return Product.objects.filter(user__email = user)
Product Serializers.py
from rest_framework import serializers
from products.models import Product
from user.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','email','password')
class ProductSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Product
fields = ('id','user','title','content','price')
Пользователь models.py
import uuid
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
# Create your models here.
class UserManager(BaseUserManager):
'''
creating a manager for a custom user model
https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#writing-a-manager-for-a-custom-user-model
https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#a-full-example
'''
def create_user(self, email, password=None):
"""
Create and return a `User` with an email, username and password.
"""
if not email:
raise ValueError('Users Must Have an email address')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Create and return a `User` with superuser (admin) permissions.
"""
if password is None:
raise TypeError('Superusers must have a password.')
user = self.create_user(email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
class User(AbstractBaseUser):
objects = models.Manager()
username = None
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
# Tells Django that the UserManager class defined above should manage
# objects of this type.
objects = UserManager()
def has_perm(self, perm, obj=None):
return self.is_superuser
def has_module_perms(self, app_label):
return self.is_superuser
def __str__(self):
return self.email
class Meta:
'''
to set table name in database
'''
db_table = "login"
class UserProfile(models.Model):
objects = models.Manager()
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
first_name = models.CharField(max_length=50, unique=False)
last_name = models.CharField(max_length=50, unique=False)
phone_number = models.CharField(max_length=10, unique=True, null=False, blank=False)
class Meta:
'''
to set table name in database
'''
db_table = "profile"
Пользователь serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('first_name', 'last_name', 'phone_number')
class UserRegistrationSerializer(serializers.ModelSerializer):
profile = UserSerializer(required=False)
class Meta:
model = User
fields = ('email', 'password', 'profile')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create_user(**validated_data)
UserProfile.objects.create(
user=user,
first_name=profile_data['first_name'],
last_name=profile_data['last_name'],
phone_number=profile_data['phone_number'],
)
return user
JWT_PAYLOAD_HANDLER = api_settings.JWT_PAYLOAD_HANDLER
JWT_ENCODE_HANDLER = api_settings.JWT_ENCODE_HANDLER
class UserLoginSerializer(serializers.Serializer):
email = serializers.CharField(max_length=255)
password = serializers.CharField(max_length=128, write_only=True)
token = serializers.CharField(max_length=255, read_only=True)
def validate(self, data):
email = data.get("email", None)
password = data.get("password", None)
user = authenticate(email=email, password=password)
if user is None:
raise serializers.ValidationError(
'A user with this email and password is not found.'
)
try:
payload = JWT_PAYLOAD_HANDLER(user)
jwt_token = JWT_ENCODE_HANDLER(payload)
update_last_login(None, user)
except User.DoesNotExist:
raise serializers.ValidationError(
'User with given email and password does not exists'
)
return {
'email':user.email,
'token': jwt_token
}
Пользователь views.py
# Create your views here.
class UserRegistrationView(CreateAPIView):
serializer_class = UserRegistrationSerializer
permission_classes = (AllowAny,)
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
status_code = status.HTTP_201_CREATED
response = {
'success' : 'True',
'status code' : status_code,
'message': 'User registered successfully',
}
return Response(response, status=status_code)
class UserLoginView(APIView):
permission_classes = (AllowAny,)
serializer_class = UserLoginSerializer
def post(self, request):
if request.method == 'POST':
if request.user.is_authenticated():
c = Product(user = request.user)
c.save()
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
response = {
'success' : 'True',
'status code' : status.HTTP_200_OK,
'message': 'User logged in successfully',
'token' : serializer.data['token'],
}
status_code = status.HTTP_200_OK
return Response(response, status=status_code)
class UserProfileView(RetrieveAPIView):
permission_classes = (IsAuthenticated,)
authentication_class = JSONWebTokenAuthentication
def get(self, request):
try:
user_profile = UserProfile.objects.get(user=request.user)
status_code = status.HTTP_200_OK
response = {
'success': 'true',
'status code': status_code,
'message': 'User profile fetched successfully',
'data': [{
'first_name': user_profile.first_name,
'last_name': user_profile.last_name,
'phone_number': user_profile.phone_number,
}]
}
except Exception as e:
status_code = status.HTTP_400_BAD_REQUEST
response = {
'success': 'false',
'status code': status.HTTP_400_BAD_REQUEST,
'message': 'User does not exists',
'error': str(e)
}
return Response(response, status=status_code)