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
но это не работает так, как я задумал...
Правильный 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
, чтобы избежать путаницы в будущем.