@Lepilov

Как создать инстансы трех моделей в одном post запросе?

Есть три взаимосвязанные модели

class VendorContacts(models.Model):
    contact_id = models.AutoField(primary_key=True)
    vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE)
    contact_name = models.CharField(max_length=45, blank=True)
    phone = models.CharField(max_length=45, blank=True)
    email = models.CharField(max_length=80, blank=True, unique=True)

    class Meta:
        db_table = 'vendor_contacts'


class VendorModuleNames(models.Model):
    vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE, primary_key=True)
    module = models.ForeignKey(Modules, models.DO_NOTHING)
    timestamp = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'vendor_module_names'
        unique_together = (('vendor', 'module'),)


class Vendors(models.Model):
    COUNTRY_CHOICES = tuple(COUNTRIES)

    vendorid = models.AutoField(primary_key=True)
    vendor_name = models.CharField(max_length=45, unique=True)
    country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
    nda = models.DateField(blank=True, null=True)
    user_id = models.ForeignKey('c_users.CustomUser', on_delete=models.PROTECT)
    timestamp = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'vendors'
        unique_together = (('vendorid', 'timestamp'),)


serializer.py

class VendorsSerializer(serializers.ModelSerializer):

    class Meta:
        model = Vendors
        fields = ('vendor_name',
                  'country',
                  'nda',
                  'parent_vendor',)


class VendorContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = VendorContacts
        fields = (
                  'contact_name',
                  'phone',
                  'email',)


class VendorModulSerializer(serializers.ModelSerializer):

    class Meta:
        model = VendorModuleNames
        fields = ('module',)


views.py

class VendorsCreateView(APIView):
    """Create new vendor instances from form"""
    serializer_class = (VendorsSerializer)

    def post(self, request, *args, **kwargs):
        vendor_serializer = VendorsSerializer(data=request.data)
        vendor_contact_serializer = VendorContactSerializer(data=request.data)
        vendor_modules_serializer = VendorModulSerializer(data=request.data)
        try:
            vendor_serializer.is_valid(raise_exception=True) \
                and vendor_contact_serializer.is_valid(raise_exception=True) \
                and vendor_modules_serializer.is_valid(raise_exception=True) \
            vendor = vendor_serializer.save(user_id=CustomUser.objects.get(id=2))
            vendor_contact_serializer.save(vendor=vendor)
            vendor_modules_serializer.save( vendor=vendor)

        except ValidationError:
            return Response({"errors": (vendor_serializer.errors,
                                        vendor_contact_serializer.errors,
                                        vendor_modules_serializer.errors
                                        )},
                            status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(request.data, status=status.HTTP_200_OK)


Я посылаю на вход json такого вида

{
        "vendor_name": "Awrddaosgsgpxsdsxjwszsslsasdjegdzasas",
        "country": "RU",
        "module": [
        	1,
        	2
        ],
        "NDA date": "",
        "contact_name": "Tim",
        "email": "tdeagst@tesasistd.gmail",
        "phone": "+3464784594940",
        "parent_vendor": "21"
    }


И получаю ошибку

{
    "module": [
        "Incorrect type. Expected pk value, received list."
    ]
}


Если в json заменю
"module": [1, 2] на "module":1 то все работает. Но у меня же связю Foreignkey, соотвественно нужна возможнось мультивыбора. Или может я не корректный json использую и list в нем не уместен? В общем что то не могу сообразить что надо сделать.
  • Вопрос задан
  • 116 просмотров
Решения вопроса 1
fox_12
@fox_12 Куратор тега Django
Расставляю биты, управляю заряженными частицами
Вы как-то костыльно все делаете. У вас должно быть как-то так примерно:

from drf_writable_nested.serializers import WritableNestedModelSerializer


class VendorContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = VendorContacts
        fields = (
                  'contact_name',
                  'phone',
                  'email',)

class VendorModulSerializer(serializers.ModelSerializer):

    class Meta:
        model = VendorModuleNames
        fields = ('module',)

class VendorsSerializer(WritableNestedModelSerializer):
    vendorcontact = VendorContactSerializer(source='vendor.vendorcontacts', many=True)
    vendormodulenames = VendorContactSerializer(source='vendor.vendormodulenames', many=True)

    class Meta:
        model = Vendors
        fields = ('vendor_name',
                  'country',
                  'nda',
                  'parent_vendor',)


И тогда большая часть кода что вы нагородили во вьюхе в post - не требуется. И создавать можно по нескольку инстансов
По sources только уточните как у вас back relations называются
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы