TypeError: Прямое присвоение обратной стороне связанного набора запрещено. Вместо этого используйте roompicture.set()
Я начинающий Django и я застрял с размещением вложенных изображений, в моем проекте я хочу разместить изображения отеля и изображения номера внутри отеля. но я получаю следующую ошибку: TypeError:
Direct assignment to the reverse side of a related set is prohibited. Use
roompicture.set() instead.
Вот код с проблемой:
room = Room.objects.create(hotel=hotel, **room_data)
Выше - мой serializers.py:
class RoomPictureSerializer(serializers.ModelSerializer):
location = Base64ImageField(max_length=None, use_url=True)
class Meta:
model = RoomPicture
fields = ['id', 'room', 'location']
class RoomSerializer(serializers.ModelSerializer):
roompicture = RoomPictureSerializer(many=True)
class Meta:
model = Room
fields = ['id', 'roompicture']
class HotelPictureSerializer(serializers.ModelSerializer):
location = Base64ImageField(max_length=None, use_url=True)
class Meta:
model = HotelPicture
fields = ['id', 'hotel', 'location']
class HotelSerializer(serializers.ModelSerializer):
hotelpicture = HotelPictureSerializer(many=True)
rooms = RoomSerializer(many=True)
class Meta:
model = Hotel
fields = ['id', 'hotelpicture', 'rooms']
def create(self, validated_data):
hotelpictures_data = validated_data.pop('hotelpicture')
rooms_data = validated_data.pop('rooms')
hotel = Complex.objects.create(**validated_data)
for hotelpicture in hotelpictures_data:
HotelPicture.objects.create(hotel=hotel, **hotelpicture)
for room_data in rooms_data:
room = Room.objects.create(hotel=hotel, **room_data)
room_pictures_data = room_data.pop('roompicture')
for room_picture_data in room_pictures_data:
RoomPicture.objects.create(room=room, **room_picture_data)
return hotel
Выше находится views.py:
class PictureViewSet(mixins.CreateModelMixin, RetrieveModelMixin, ListModelMixin,
GenericViewSet, UpdateModelMixin):
queryset = Hotel.objects.all()
serializer_class = HotelSerializer
Выше мой model.py:
class Hotel(models.Model):
country = models.CharField()
hotel_name = models.CharField(max_length=20)
street = models.CharField(max_length=100)
city = models.CharField(max_length=100, default='')
class HotelPicture(models.Model):
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
location = models.ImageField(upload_to='images/')
class Room(models.Model):
hotel = models.ForeignKey(Hotel, on_delete=models.DO_NOTHING, related_name='rooms')
floor = models.CharField(max_length=10)
room-number = models.IntegerField()
class RoomPicture(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
location = models.ImageField(upload_to='images/')
Ниже мой url:
router.register(r'pictures', PictureViewSet)
Может ли кто-нибудь помочь мне, пожалуйста? Заранее спасибо.
Прежде всего, нам нужно перепроектировать ваши модели.
Не обязательно создавать отдельные модели для изображений, можно создать модель для всех изображений, и эта модель будет иметь отношения M2M
с Hotel
и Room
следующим образом:
class Pictures(models.Model):
picture = models.ImageField(upload_to='images/')
Затем установите связь между этой моделью и другими моделями:
class Hotel(models.Model):
country = models.CharField()
hotel_name = models.CharField(max_length=20)
street = models.CharField(max_length=100)
city = models.CharField(max_length=100, default='')
pictures = models.ManyToManyField(Pictures)
class Room(models.Model):
hotel = models.ForeignKey(Hotel, on_delete=models.DO_NOTHING, related_name='rooms')
pictures = models.ManyToManyField(Pictures)
floor = models.CharField(max_length=10)
room-number = models.IntegerField()
Второй шаг - создание сериализатора для этих моделей, я предпочитаю использовать serializers.Serializer
class PicturesSerializer(serializers.Serializer):
picture = serializers.ImageField()
class HotelSerializer(serializers.Serializer):
picture = PicturesSerializer(many=True)
# List other fields
class RoomSerializer(serializers.Serializer):
picture = PicturesSerializer(many=True)
# List other fields
Третьим шагом является создание представления.
Допустим, вы хотите создать Hotel
.
В API
в соответствии с HotelSerializer
вы отправите данные отеля + список изображений, затем вы сделаете следующее: получите эти данные и создадите Hotel
, затем пройдете по изображениям, создадите их, затем поместите в Hotel
Тот же подход с Room
.