简体   繁体   中英

Creating and updating data from API answerI to Django REST project (MySQ)?

I have a Django REST project. I have a models User, Store and Warehouse.

And I have a module with marketplace parser, that gets data from marketplace API. In this module there is a class Market and a method "get_warehouses_list". This method returns a JSON with a STORE's warehouse list. Examle answer:

{
"result": [
{
"warehouse_id": 1,
"name": "name1",
"is_rfbs": false
},
{
"warehouse_id": 2,
"name": "name2",
"is_rfbs": true
}
]
}

What I have to do is to make creating and updating methods to set and update this warehouse list into my MySQL DB (with creating an endpoint for setting and updating this data).

I don't know what is incorrect in my code, but when I send POST request to my endpoint in urls.py

router.register("", WarehouseApi, basename="warehouse")

I get 400 error instead of setting warehouse list into my DB.

My code:

user/models.py

class User(AbstractUser):
    username = models.CharField(
        max_length=150,
        unique=True,
        null=True)
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        unique=True,
        editable=False)

store/models.py `

class Store(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.PROTECT)
    name = models.CharField(max_length=128,
                            blank=True)
    type = models.PositiveSmallIntegerField(
        choices=MARKET,
        default=1,
        verbose_name="Type API") 
    api_key = models.CharField(max_length=128)
    client_id = models.CharField(max_length=128)

warehouses/models.py

class Warehouse(models.Model):
    store = models.ForeignKey(
        Store,
        on_delete=models.СASCAD, null=True)
    warehouse_id = models.BigIntegerField(
        unique = True,
        null = True)
    name = models.CharField(
        max_length=150)
    is_rfbs = models.BooleanField(default=False)

` serializers.py

`

class WarehouseSerializer(serializers.ModelSerializer):

    class Meta:
        model = Warehouse
        fields = '__all__'

    store = serializers.CharField(max_length=50)
    warehouse_id = serializers.IntegerField()
    name = serializers.CharField(max_length=100)
    is_rfbs = serializers.BooleanField()
    is_default_warehouse = serializers.BooleanField()

class WarehouseUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Warehouse
        fields = ('name', 'is_rfbs',)

    def save(self, **kwargs):
        self.instance.name = self.validated_data["name"]
        self.instance.is_rfbs = self.validated_data["is_rfbs"]
        self.instance.save
        returself.instance

views.py

class WarehouseApi(ModelViewSet):

    def get_queryset(self):
        return Warehouse.objects.filter(
            store__user_id=self.request.user.pk)\
            .order_by('-warehouse_id')

    def get_serializer_class(self):
        if self.request.method in ("PUT", "PATCH"):
            return WarehouseUpdateSerializer
        return WarehouseSerializer

    def create(self, request, *args, **kwargs):
        st = Store.objects.filter(user=self.request.user,  # getting all stores with marketplace type = 1
                                  type=1)
        for e in st:
            api = Market(api_key=e.api_key,                # call parser class Market
                                client_id=e.client_id)
            data = api.get_warehouses_list()               # call Market's method 'get_warehouses_list'
        if len(data['result']) > 0:
            for wh in data['result']:
                alreadyExists = Warehouse.objects.filter(  # check if warehouses with such ID already exists
                        warehouse_id=wh.get(
                        'warehouse_id')).exists()
                if alreadyExists:
                        return Response({'message':'Warehouse ID already exists'})
                else:
                    wh_data = {
                        'warehouse_id': wh.get('warehouse_id'),
                        'name': wh.get('name'),
                        'is_rfbs': wh.get('is_rfbs')
                        }
                    Warehouse.objects.create(**wh_data)
                    warehouses = Warehouse.objects.filter(
                    marketplace=1, store__in=st).order_by(
                    '-warehouse_id')
                    s = WarehouseSerializer(warehouses, many=True)
                    return Response(status=200, data=s.data)
        else:
            return Response(status=400,
                        data={"Error": "Store has no warehouses"})

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        api = Market(api_key=instance.store.api_key,
                            client_id=instance.store.client_id)
        warehouses = Warehouse.objects.filter(store__user_id=self.request.user,
                                            store__type=1)     # get all store's warehouses
        if warehouses:
            for warehouse in warehouses:
                r = api.get_warehouses_list()               # call Market's method 'get_warehouses_list'
                if len(r['result']) > 0:
                    for wh in r['result']:
                        if serializer.validated_data["name"] != wh['name']:
                            instance.name = wh['name']
                            instance.save(['name'])
                        if serializer.validated_data["is_rfbs"] != wh['is_rfbs']:
                            instance.name = wh['is_rfbs']
                            instance.save(['is_rfbs'])
                        serializer = WarehouseUpdateSerializer(instance)
                        return Response(serializer.data, {
                                    'status': status.HTTP_200_OK,
                                    'message': 'Warehouse updated successfully'
                                    })
                else:
                    return Response({
                                    'message': 'Store has no warehouses'
                                    })
        else:
            return Response({
                            'message': 'There are no saved warehouses in DB'
                            })

`

The 400 Error might be caused by a number of reasons. Do you have any logging information you can provide? Either from the Python logs or using the browser developer tools?

In your own code you are returning a 400 code if the variable data is empty. Are you sure you are not hitting this validation?

If nothing turns up, I advise you to add some exception dealing and logging capabilities to your own code as it seems to be very unprotected and post that information here if needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM