如何在Django Rest Framework的ModelViewSet中声明user_id?

huangapple go评论82阅读模式
英文:

How to declare user_id on ModelViewSet in DjangoRestFramework

问题

Foreignkey根是User>Comparelist>obj

我不知道我的代码有什么问题。
错误信息告诉我comparelist需要user_id。

accounts>models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

from .managers import UserManager
from core.models import TimestampedModel


class User(AbstractBaseUser, PermissionsMixin, TimestampedModel):
    email = models.EmailField(max_length=30, unique=True, null=False, blank=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'

accounts>serializers.py

from .models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

    def create(self, validated_data):
        user = User.objects.create_user(
            email = validated_data['email'],
            password = validated_data['password']
        )
        return user

ImageConverters>models.py

from django.db import models

from accounts.models import User


class CompareList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="owner")
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(auto_now_add=True)


class Obj(models.Model):
    comparelist = models.ForeignKey(CompareList, on_delete=models.CASCADE)
    object_name = models.CharField(max_length=100)
    image = models.URLField(max_length=500)

ImageConverters>serializers.py

from .models import CompareList, Obj
from rest_framework import serializers


class ObjSerializer(serializers.ModelSerializer):
    class Meta:
        model = Obj
        fields = ['object_name', 'image']


class CompareListSerializer(serializers.ModelSerializer):
    objs = ObjSerializer(many=True, read_only=True)

    class Meta:
        model = CompareList
        fields = ['id', 'objs']

    def create(self, validated_data):
        images_data = self.context['request'].FILES
        texts_data = self.context['request'].data
        comparelist = CompareList.objects.create(**validated_data)
        for image_data, text_data in zip(images_data.getlist('image'), texts_data.getlist('object_name')):
            Obj.objects.create(comparelist=comparelist, image=image_data, object_name=text_data)
        return comparelist

ImageConverters>views.py

from rest_framework.viewsets import ModelViewSet

from .models import CompareList, Obj
from .serializers import CompareListSerializer, ObjSerializer


class CompareListCreate(ModelViewSet):
   queryset = CompareList.objects.all()
   serializer_class = CompareListSerializer



class ObjListCreate(ModelViewSet):
    queryset = Obj.objects.all()
    serializer_class = ObjSerializer

我向服务器发送了POST请求,但是收到了错误消息。

点击这里查看图片

英文:

Foreignkey root is
User> Comparelist > obj

I don't know what's wrong with my code.
Error message said me comparelist required user_id

accounts> models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

from .managers import UserManager
from core.models import TimestampedModel


class User(AbstractBaseUser, PermissionsMixin, TimestampedModel):
    email = models.EmailField(max_length=30, unique=True, null=False, blank=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'

accounts> serializers.py

from .models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

    def create(self, validated_data):
        user = User.objects.create_user(
            email = validated_data['email'],
            password = validated_data['password']
        )
        return user

ImageConverters> models.py

from django.db import models

from accounts.models import User


class CompareList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="owner")
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(auto_now_add=True)


class Obj(models.Model):
    comparelist = models.ForeignKey(CompareList, on_delete=models.CASCADE)
    object_name = models.CharField(max_length=100)
    image = models.URLField(max_length=500)

ImageConverters> serializers.py

from .models import CompareList, Obj
from rest_framework import serializers


class ObjSerializer(serializers.ModelSerializer):
    class Meta:
        model = Obj
        fields = ['object_name', 'image']


class CompareListSerializer(serializers.ModelSerializer):
    objs = ObjSerializer(many=True, read_only=True)

    class Meta:
        model = CompareList
        fields = ['id', 'objs']

    def create(self, validated_data):
        # print(dir(self))
        print(self)
        print('------------------')
        images_data = self.context['request'].FILES
        texts_data = self.context['request'].data
        comparelist = CompareList.objects.create(**validated_data)
        print(texts_data)
        for image_data, text_data in zip(images_data.getlist('image'), texts_data.getlist('object_name')):
            print(image_data, text_data)
            Obj.objects.create(comparelist=comparelist, image=image_data, object_name=text_data)
        return comparelist

ImageConverters> views.py

from rest_framework.viewsets import ModelViewSet

from .models import CompareList, Obj
from .serializers import CompareListSerializer, ObjSerializer


class CompareListCreate(ModelViewSet):
   queryset = CompareList.objects.all()
   serializer_class = CompareListSerializer



class ObjListCreate(ModelViewSet):
    queryset = Obj.objects.all()
    serializer_class = ObjSerializer

I sent post to server. But I got Error

enter image description here

答案1

得分: 1

您正在尝试创建一个没有用户字段的CompareList对象,这违反了数据库关系,因为创建CompareList对象需要用户字段。如果经过身份验证的用户是CompareList对象的所有者(假设只有授权用户才能执行此操作),请按照以下方式更新您的序列化器的create方法:

def create(self, validated_data):
    images_data = self.context['request'].FILES
    texts_data = self.context['request'].data
    comparelist = CompareList.objects.create(**validated_data, user=self.context['request'].user)
    for image_data, text_data in zip(images_data.getlist('image'), texts_data.getlist('object_name')):
        Obj.objects.create(comparelist=comparelist, image=image_data, object_name=text_data)
    return comparelist

请注意,这只是一个示例代码片段,您需要根据您的实际需求进行适当的修改。

英文:

You are trying to create a CompareList object without user field. Which violate with database relationship since user is required to create CompareList object.
If authenticated user is the owner of a CompareList object(Assuming only authorized user should be authorized to perform this action). update your serializer create method like this:

def create(self, validated_data):
    # print(dir(self))
    print(self)
    print('------------------')
    images_data = self.context['request'].FILES
    texts_data = self.context['request'].data
    comparelist = CompareList.objects.create(**validated_data, user=self.context['request'].user)
    print(texts_data)
    for image_data, text_data in zip(images_data.getlist('image'), texts_data.getlist('object_name')):
        print(image_data, text_data)
        Obj.objects.create(comparelist=comparelist, image=image_data, object_name=text_data)
    return comparelist

huangapple
  • 本文由 发表于 2023年8月9日 15:34:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定