多个模型保存在POST请求中。 (数据无效。预计字典,但得到列表。)

时间:2017-03-17 17:14:16

标签: django django-models django-rest-framework django-serializer

我有两个型号。偏好和CustomerPreference。我想一次保存多个customer_preferences。现在我得到以下错误。

class PreferencesViewSet(viewsets.ModelViewSet):
    serializer_class = PreferencesSerializer
    queryset = Preferences.objects.all()


class CustomerPreferenceViewSet(viewsets.ModelViewSet):
    serializer_class = CustomerPreferencesSerializer
    queryset = CustomerPreferences.objects.all()

    model = CustomerPreferences

    def get_queryset(self):
        queryset = CustomerPreferences.objects.all()
        customer_id = self.request.query_params.get('customer_id', None)
        if customer_id is not None:
            queryset = queryset.filter(customer=customer_id)
        return queryset

    def get_serializer_class(self):
        if self.action == 'list' or self.action == 'retrieve':
            return CustomerPreferencesListSerializer
        return CustomerPreferenceSaveSerializer

models.py

class PreferencesSerializer(serializers.ModelSerializer):
    model = Preferences

    class Meta:
        model = Preferences
        fields = '__all__'


class CustomerPreferencesListSerializer(serializers.ModelSerializer):
    model = CustomerPreferences
    preference = PreferencesSerializer()

    class Meta:
        model = CustomerPreferences
        exclude = ('id','user',)


class CustomerPreferencesSerializer(serializers.ModelSerializer):
    model = CustomerPreferences
    user = serializers.CharField(read_only=True)

    class Meta:
        model = CustomerPreferences
        fields = '__all__'


class CustomerPreferenceSaveSerializer(serializers.ModelSerializer):
    customer_preferences = CustomerPreferencesSerializer()

    class Meta:
        model = Preferences
        fields = ( 'customer_preferences',)

    def create(self, validated_data):
        request = self.context.get('request')
        customer_preferences_data = validated_data.pop('customer_preferences')
        customer_id = request.POST.get('customer', None)

        for cust_prefernce in customer_preferences_data:
            cust_prefernce_obj = CustomerPreferences.objects.create(
                preference_id=cust_prefernce['preference'],
                status=cust_prefernce['status'],
                customer = customer_id,
                user = request.user
            )
        return CustomerPreferences.objects.all()

views.py

router.register(r'customer-preference', views.CustomerPreferenceViewSet, 'customers')
router.register(r'preference', views.PreferencesViewSet, 'preferences')

serialzers.py

{
  "customer":"ddf30356-9dba-4e0b-9ae7-9c589dff004",
  "customer_preferences":  [
    {
      "id": "20d1a84a-bde8-45dd-81bc-ce2fda855a91",
      "status": "like"
    },
    {
      "id": "df791115-dd5b-4446-b954-24f7c1bbc4f4",
      "status": "dislike"
    },
    {
      "id": "4a3c317f-f202-4b6f-ae9d-598c7aff5fe7",
      "status": ""
    },
    {
      "id": "9ac24dda-df86-4f11-a18d-6f438929751d",
      "status": "neutral"
    }
  ]
}

urls.py

{{1}}

我想提交多个customer_preferences,如下所示。无法从序列化程序访问“客户”

POST请求

{{1}}

2 个答案:

答案 0 :(得分:1)

我已通过更新序列化程序解决了这些问题,如下所示。

serializers.py

class CustomerPreferencesSerializer(serializers.ModelSerializer):
    model = CustomerPreferences
    user = serializers.CharField(read_only=True)
    class Meta:
        model = CustomerPreferences
        fields = '__all__'


class CustomerPreferencesListSerializer(serializers.ModelSerializer):
    model = Preferences
    customer_preferences = serializers.SerializerMethodField()

    def get_customer_preferences(self, obj):
        request = self.context.get('request')
        customer_id = request.query_params.get('customer_id', None)
        customer_pref = CustomerPreferences.objects.filter(preference_id=obj, customer=customer_id)
        serializer = CustomerPreferencesSerializer(customer_pref, many=True)
        return serializer.data



    class Meta:
        model = Preferences
        fields = ('id', 'title','status')


class CustomerPreferenceSaveSerializer(serializers.Serializer):
    model = Customer
    customer_preferences = CustomerPreferencesSerializer(source='customer_customer_preferences', many=True,read_only=True)

    class Meta:
        model = Customer
        fields = ('customer','customer_preferences',)

    def create(self, validated_data):
        request = self.context.get('request')
        customer = request.data.get('customer', None)
        customer_preferences_data = request.data.get('customer_preferences', [])

        # first delete all entries of the given customer
        customer_preferences_obj = CustomerPreferences.objects.filter(customer=customer)
        customer_preferences_obj.delete()

        for cust_prefernce in customer_preferences_data:
            cust_prefernce_obj = CustomerPreferences.objects.create(
                preference_id=cust_prefernce['preference'],
                status=cust_prefernce['status'],
                customer_id = customer,
                user = request.user
            )

        return Customer.objects.all().get(id=customer)

views.py

class PreferencesViewSet(viewsets.ModelViewSet):
serializer_class = PreferencesSerializer
queryset = Preferences.objects.all()


class CustomerPreferenceViewSet(viewsets.ModelViewSet):
    serializer_class = CustomerPreferencesSerializer
    queryset = CustomerPreferences.objects.all()

    model = CustomerPreferences

    def get_queryset(self):
        queryset = Preferences.objects.all()
        return queryset

    def get_serializer_class(self):
        if self.action == 'list' or self.action == 'retrieve':
            return CustomerPreferencesListSerializer
        return CustomerPreferenceSaveSerializer

答案 1 :(得分:0)

您已发布模型CustomerPreferences,该模型定义了客户与偏好之间的映射。

您发布的序列化程序是此映射的序列化程序 - 它序列化了一个首选项和一个客户之间的关系。

我认为您希望显示/更新一位客户的偏好,因此我的答案基于该假设。

使用您当前的模型结构,您可以获得customer.customer_customer_preferences.all()的一位客户的CustomerPreferences。您需要一个CustomerSerializer使用CustomerPreferencesSerializer(many = True)来处理多个首选项:

class CustomerSerializer(Serializer):
     model = Customer
     # ... more fields
     customer_preferences = CustomerPreferencesSerializer(source='customer_customer_preferences', many=True)

代码未经过测试。您可能需要自定义代码才能保存。

请参阅http://www.django-rest-framework.org/api-guide/relations/#nested-relationships