Drf: serializers.ModelField > Как я могу получить user_id соответствующим образом?

Я хочу реализовать автоматическое сохранение 'user_id' на бэкенде без получения его от клиента. (при создании объекта!). Вот мой код.

models.py

class User(AbstractUser):
    username = None
    email = models.EmailField(max_length=255, unique=True)
    
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    
    objects = UserManager()
    social_profile = models.URLField(null=True,blank=True)
    realname = models.CharField(max_length=50, blank=True)
    nickname = models.CharField(max_length=50, null=True, unique=True) 
    address = models.CharField(max_length=200, blank=True)
    phone = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.email

class Item(models.Model):
    user_id = models.ForeignKey(User, related_name='item_sets', on_delete=models.CASCADE)
    category_id = models.ForeignKey(Category, related_name='item_sets', on_delete=models.DO_NOTHING)
    description = models.TextField()
    feature = models.TextField()
    product_defect = models.TextField()
    size = models.CharField(max_length=6)
    height = models.DecimalField(max_digits=4, decimal_places=1, default=0)
    weight = models.DecimalField(max_digits=4, decimal_places=1, default=0)
    condition = models.CharField(max_length=20)
    price = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    sold_out = models.BooleanField(default=False)

    def __str__(self):
        return self.description
view.py

class ItemViewSet(ModelViewSet):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['description']    # ?search=
    ordering_fields = ['created_at']  # ?ordering=
    ordering = ['-created_at']
    authentication_classes = (JWTCookieAuthentication,)

    # create
    def create(self, request, *args, **kwargs):
        city = request.data['city']
        gu = request.data['gu']
        dong = request.data['dong']
        if city is not None and gu is not None and dong is not None:
            location = Location.objects.get(
                Q(city=city) & Q(gu=gu) & Q(dong=dong)
            )
        else:
            return Response(
                {"message": "주소정보를 모두 입력해주세요."},
                status=status.HTTP_400_BAD_REQUEST
            )
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        new_item = Item.objects.get(id=serializer.data['id'])
        headers = self.get_success_headers(serializer.data)
        LocationSet.objects.create(item_id=new_item, location_id=location)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    # here!
    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)
serializers.py

class ItemSerializer(serializers.ModelSerializer):
    photos = PhotoSerializer(source='photo_sets', many=True, read_only=True)
    style_photos = StylePhotoSerializer(source='style_photo_sets', many=True, read_only=True)
    user_id = serializers.ModelField(model_field=User()._meta.get_field('id'), required=False) #here!

    class Meta:
        model = Item
        fields = '__all__'

    # Photo, StylePhoto
    def create(self, validated_data):
        images_data = self.context['request'].FILES
        item = Item.objects.create(**validated_data)
        for photo_data in images_data.getlist('photos_data'):
            Photo.objects.create(item_id=item, photo=photo_data)
        for style_photo_data in images_data.getlist('style_photos_data'):
            StylePhoto.objects.create(item_id=item, user_id=self.context['request'].user,
                                      photo=style_photo_data)
        print(User()._meta.get_field('id'))
        return item

поэтому я переопределил perform_create() в views.py и написал 'user_id = serializers.ModelField(model_field=User()._meta.get_field('id'), required=False)' в serializers.py но это не работает так, как я задумал... enter image description here

Правильный user_id равен 8. но у моего объекта 18...:< 18 - это только item_id, а не user_id... что я должен сделать, чтобы исправить эту ошибку?

Попробуйте это:

views.py : используйте метод perform_create() для сохранения user_id.

Примечание: пользователь должен быть аутентифицирован, чтобы мы могли получить его из запроса.

class ItemViewSet(ModelViewSet):
    # your code ...

    # create
    def create(self, request, *args, **kwargs):
        # your code code ...

    def perform_create(self, serializer):       # new
        serializer.save(user_id=self.request.user)

serializers.py : Получите user_id из базы данных и сделайте его доступным для чтения, так как он не должен редактироваться пользователем:

class ItemSerializer(serializers.ModelSerializer):
    # your code ..
    user_id = serializers.ReadOnlyField(source='user_id.id')   # new

    class Meta:
        model = Item
        fields = '__all__'

    # Photo, StylePhoto
    def create(self, validated_data):
        images_data = self.context['request'].FILES
        item = Item.objects.create(**validated_data)
        for photo_data in images_data.getlist('photos_data'):
            Photo.objects.create(item_id=item, photo=photo_data)
        for style_photo_data in images_data.getlist('style_photos_data'):
            StylePhoto.objects.create(item_id=item,photo=style_photo_data)   # new
        print(User()._meta.get_field('id'))
        return item

Я бы также рекомендовал вам изменить поле user_id на что-то вроде owner, чтобы избежать путаницы в будущем.

Вернуться на верх