All Articles

Server System/Django

[Django] ManyToManyField Rest Framework Create and Update

검색했던 것들 

> Direct assignment to the forward side of a many-to-many set is prohibited. Use .set() instead

> django manytomanyfield set

> needs to have a value for field "id" before this many-to-many relationship can be used.

 

참조: https://stackoverflow.com/questions/61537923/update-manytomany-relationship-in-django-rest-framework

#serializers.py
class PackageSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = Package
        fields = "__all__"


class OrderSerializer(serializers.ModelSerializer):
    package = PackageSerializer(many=True)

    def get_or_create_packages(self, packages):
        package_ids = []
        for package in packages:
            package_instance, created = Package.objects.get_or_create(pk=package.get('id'), defaults=package)
            package_ids.append(package_instance.pk)
        return package_ids

    def create_or_update_packages(self, packages):
        package_ids = []
        for package in packages:
            package_instance, created = Package.objects.update_or_create(pk=package.get('id'), defaults=package)
            package_ids.append(package_instance.pk)
        return package_ids

    def create(self, validated_data):
        package = validated_data.pop('package', [])
        order = Orders.objects.create(**validated_data)
        order.package.set(self.get_or_create_packages(package))
        return order

    def update(self, instance, validated_data):
        package = validated_data.pop('package', [])
        instance.package.set(self.create_or_update_packages(package))
        fields = ['order_id', 'is_cod']
        for field in fields:
            try:
                setattr(instance, field, validated_data[field])
            except KeyError:  # validated_data may not contain all fields during HTTP PATCH
                pass
        instance.save()
        return instance

    class Meta:
        model = Orders
        fields = "__all__"

#views.py
class OrderViewSet(viewsets.ModelViewSet):
    serializer_class = OrderSerializer
    queryset = Orders.objects.all()

 

 

추가

class CombinedScenarioSerializer(serializers.ModelSerializer): 
    ID = serializers.IntegerField(read_only=True, )
    Scenarios = serializers.SlugRelatedField(many=True, slug_field='ID', queryset=SeparatedScenario.objects.all())
    #Scenarios = IDListingField(queryset=SeparatedScenario.objects.all(), many=True)
    
    class Meta: 
        model = CombinedScenario
        fields = '__all__'

    def get_or_create_packages(self, scenarios):
        package_ids = []
        for scenario in scenarios:
            package_instance, created = SeparatedScenario.objects.get_or_create(pk=scenario.ID, defaults=scenario)
            package_ids.append(package_instance.pk)
        return package_ids

    def create_or_update_packages(self, scenarios):
        package_ids = []
        for scenario in scenarios:
            package_instance, created = SeparatedScenario.objects.update_or_create(pk=scenario.ID, defaults=scenario)
            package_ids.append(package_instance.pk)
        return package_ids

    def create(self, validated_data):
        separated_scenarios = validated_data.pop("Scenarios")
        instance = CombinedScenario.objects.create(**validated_data)
        instance.save()
        scenarios = self.get_or_create_packages(separated_scenarios)
        instance.Scenarios.set(scenarios)
        return instance

    def update(self, instance, validated_data):
        instance.save()
        return instance

 

 

 

'Server System > Django' 카테고리의 다른 글

Create User in Shell  (0) 2022.05.31
[Django Rest] Allow Empty String in CharField  (0) 2022.05.27
Django and GraphQL  (0) 2020.05.29