Валидация сериализатора DRF - отбрасывать неудачные элементы, сохранять удачные?

У меня есть конечная точка (POST, APIView), которая ожидает большие куски данных, которые должны быть проверены с помощью сериализаторов. Однако, по многим причинам бывают случаи, когда я хотел бы отбросить несколько из них, которые не прошли валидацию. Остальные я все еще хочу добавить.

Например, я бы хотел побегать :

serializer = ListingSerializer(data=request.data, many=True)
if serializer.is_valid():
   serializer.save()

Допустим, у нас есть таблица списков, которая имеет внешний ключ к таблице компаний. Поэтому у меня есть вложенный сериализатор компании в качестве поля. У компании есть только имя. Для экономии производительности я получаю все компании в методе init, поэтому is_valid() делает только один запрос (аналогично select_related).

Проблема заключается в том, что если одна компания не существует, то вся функция is_valid() завершится неудачей, и я не смогу запустить serializer.save(). Есть ли какой-нибудь элегантный способ решить эту проблему, отбросив отдельные элементы, которые не прошли проверку is_valid(), чтобы я мог запустить serializer.save()?

class CompanyStringSerializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = ("name",)


class ListingSerializer():
    company = CompanyStringSerializer()

    def __init__(self, *args, **kwargs):
        """
        This is executed when the serializer initializes (meaning the query will only run once)
        """
        self.companies = Company.objects.filter(enabled=True)
        super().__init__(*args, **kwargs)

    def validate_company(self, value):
        """
        This will run on each item & check if the items company name exists in the list of companies
        """
        try:
            company = next(
                item for item in self.companies if item.name == value["name"]
            )
        except StopIteration:
            print(f"company did not exist: {value['name']}")
            raise ValidationError("No such company exists")
        return company

    class Meta:
        model = Listing
        list_serializer_class = ListingListSerializer
        fields = "__all__"
Вернуться на верх