Есть модели :
class City(models.Model):
name = models.CharField(max_length=50, default='')
def __str__(self):
return self.name
class Street(models.Model):
name = models.CharField(max_length=50)
city = models.ForeignKey(City, on_delete=models.CASCADE)
def __str__(self):
return f"{self.city}: {self.name}"
class Shop(models.Model):
name = models.CharField(max_length=50)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
street = models.ForeignKey(Street, on_delete=models.SET_NULL, null=True)
house = models.SmallIntegerField()
opening_time = models.TimeField()
closing_time = models.TimeField()
def __str__(self):
return f"{self.name} по адрессу {self.street} - {self.house}. Работает с {self.opening_time} до {self.closing_time}"
Есть сериализаторы:
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
fields = ['id', 'name']
class StreetSerializer(serializers.ModelSerializer):
city = CitySerializer()
class Meta:
model = Street
fields = ['id', 'name', 'city']
# Not working but it's not important, becase i can replace id of city by name in StringRelatedField
def create(self, validated_data):
city_data = validated_data.pop('city')
city = City.objects.create(**city_data)
street = Street.objects.create(**validated_data)
class ShopSerializer(serializers.ModelSerializer):
city = CitySerializer()
street = StreetSerializer()
class Meta:
model = Shop
fields = ['id', 'name', 'city', 'street', 'house', 'opening_time', 'closing_time']
# This is important, it have to work
def create(self, validated_data):
city_data = validated_data.pop('city')
city = City.objects.create(name=city_data['name'])
street_data = validated_data.pop('street')
street = Street.objects.create(name = street_data['name'], city = city)
shop = Shop.objects.create(**validated_data)
# This occures NoneType
# shop.city.add(city)
# This not working at all
# shop.street.add(street)
return shop
Всё вроде бы хорошо, но есть нюанс. Если оставить всё вв таком ввиде, то при пост запросе вместо city и street при сериализации Shop будут значения Null. Если попробывать раскомментить shop.street.add(street), то вызывается ошибка
AttributeError: 'NoneType' object has no attribute 'add'. Если попытаться использовать а-ля словарь или класс объявления (shop['street'] = street и shop.street = street), то вызываются ошибки, что словарный синтаксис не поддерживается, а для класса опять NoneType вылезает. Что делать с этим не пойму.