Django остальные рамки: POST на многие ко многим пунктам - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть модель TransactionType, и я реализовал метод viewset для создания типа транзакции, как показано ниже.В настоящее время я могу публиковать только отдельные элементы credit_account или debit_account, как показано в этой полезной нагрузке:

{"name":"Repair and Maintenance","credit_account":16,"debit_account":38}

Я бы отправил несколько credit_accounts и debit_accounts таким образом, чтобы моя полезная нагрузка выглядела примерно так:

{"name":"Repair and Maintenance","credit_account":[16,4,5],"debit_account":[38,7]}

Какой эффективный способ сделать это?

class TransactionType(models.Model):
    name = models.CharField(max_length=255)
    organization = models.IntegerField(null=True, blank=False)  
    credit_account = models.ManyToManyField(Account,related_name='credit_account', verbose_name="Account to Credit")
    debit_account = models.ManyToManyField(Account,related_name='debit_account',verbose_name="Account to Debit")

    def __str__(self):
        return '{}'.format(self.name)

метод viewset

def create(self, request, format=None):

    name = request.data['name']

    try:

        trans_type_obj = TransactionType.objects.create(name=name,
                credit_account=Account.objects.get(id=request.data['credit_account'
                ]),
                debit_account=Account.objects.get(id=request.data['debit_account'
                ]), organization=get_auth(request))

        serializer = CreateTransactionTypeSerializer(trans_type_obj)
    except Exception, e:
        raise e

    return Response(data=serializer.data,
                    status=status.HTTP_201_CREATED)

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018
def create(self, request,*args, **kwargs):

        name = request.data.pop('name')
        credits = request.data.pop('credit_account')
        debits = request.data.pop('debit_account')
        try:

            trans_type_obj = TransactionType.objects.create(name=name, organization=get_auth(request))
            for item in credits:
                trans_type_obj.credit_account.add(item)
            for item in debits:
                trans_type_obj.debit_account.add(item)

            serializer = TransactionTypeSerializer(trans_type_obj)
        except Exception as e:
            raise e

        return Response(data=serializer.data, status=status.HTTP_201_CREATED)
0 голосов
/ 14 декабря 2018

вы можете создать один сериализатор со следующими полями

class TransactionTypeSerializer(serializers.ModelSerializer):
    credit_account = serializers.PrimaryKeyRelatedField(queryset=Account.objects.all(), many=True)
    debit_account = serializers.PrimaryKeyRelatedField(queryset=Account.objects.all(), many=True)

    class Meta:
         model = TransactionType
         fields = __all__

теперь в представлениях

def create(self, request, *args, **kwargs):
   serializer = TransactionTypeSerializer(data=request.data)
   serializer.is_valid(raise_exception=True)
   serializer.save()
   return Response(serializer.data)
0 голосов
/ 14 декабря 2018

Используйте ManyToManyField.add(), как показано ниже,

def create(self, request, format=None):
    name = request.data['name']

    try:

        <b>trans_type_obj = TransactionType.objects.create(name=name, organization=get_auth(request))
        trans_type_obj.credit_account.add(*[credit_obj for credit_obj in Account.objects.filter(id__in=request.data['credit_account'])])
        trans_type_obj.debit_account.add(*[debit_obj for debit_obj in Account.objects.filter(id__in=request.data['debit_account'])])</b>
        serializer = CreateTransactionTypeSerializer(trans_type_obj)
    except Exception, e:
        raise e

    return Response(data=serializer.data,
                    status=status.HTTP_201_CREATED)

ОБНОВЛЕНИЕ-1
как @ Даниэль Роузман сказал, также можно сделать то же самое без компиляции списка, как

trans_type_obj.credit_account.add(*Account.objects.filter(id__in=request.data['credit_account']))
trans_type_obj.debit_account.add(*Account.objects.filter(id__in=request.data['debit_account']))
...