2

I can not get a clear answer after two days of searching for what must probably be one of the most common things to do with a DRF:

I have the following model:

class ProcessedStockAmounts(models.Model):
    prodName = models.ForeignKey(Productlist, on_delete=models.CASCADE, blank=False, unique=False)
    amount = models.CharField(unique=False, max_length=255)
    time = models.ForeignKey(StockTakingTimes, on_delete=models.CASCADE, blank=False, unique=False, default=1)

    def __str__(self):
        return str(self.prodName)

And I am returning a JSON object via my API that looks like this:

[{'prodName': 'SV1', 'amount': '1111111', 'time' : 1}]

When I insert my prodName with a value it has no problem, but obviously my user will not know the prodName ID and only the prod name. So when I try to insert the above I get the following error:

ValueError: Cannot assign "'SV1'": "ProcessedStockAmounts.prodName" must be a "Productlist" instance.

This was the closest I got to an answer and when I do the following it actually inserts:

p = ProcessedStockAmounts(amount='33', prodName = Productlist.objects.get(productid = 'SV1'), time = StockTakingTimes.objects.get(times='06:00'))
p.save()

but giving data this way is obviously defeating the purpose.

My serializer looks like the following:

class TestSerializer(serializers.ModelSerializer):

    # time = serializers.SlugRelatedField(read_only=True, slug_field='time')
    prodName = serializers.CharField()
    # prodName = serializers.SlugRelatedField(read_only=True, slug_field='prodName')

    class Meta:
        model = ProcessedStockAmounts
        fields = ('prodName','amount','time')

With my view:

class InsertMultiProcessedStock(APIView):

    def post(self, request, format='json'):
        serializer = TestSerializer(data = request.data, many=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else: 
            return Response(serializer.errors)

Productlist model:

class Productlist(models.Model):
    productid = models.CharField(unique=True, max_length=20)  # Field name made lowercase.
    proddescription = models.CharField(db_column='prodDescription', max_length=255, blank=True, null=True)  # Field name made lowercase.
    packaging = models.ForeignKey(Packaging, on_delete=models.CASCADE, blank=True, null=True)
    unitweight = models.FloatField(db_column='unitWeight', blank=True, null=True)  

    def __str__(self):
        return self.productid
Alfa Bravo
  • 1,961
  • 2
  • 25
  • 45
  • You can get the product from product name and pass that when saving using serializer, see this http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save – Rohan Jul 09 '18 at 08:31

2 Answers2

3

This would have been easier if you had the related model. But the commented-out slugrelatedfield is the way you should do it, using the actual field name:

prodName = serializers.SlugRelatedField(read_only=False, slug_field='productid')
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Have tried it a few ways so far, but do not get past the following error: `Relational field must provide a 'queryset' argument, override 'get_queryset', or set read_only='True'.` I have added related model as well – Alfa Bravo Jul 09 '18 at 09:25
  • 1
    Finally got is with `prodName = serializers.SlugRelatedField(read_only=False, slug_field='productid', queryset=Productlist.objects.all())` – Alfa Bravo Jul 09 '18 at 10:05
0

Your serializer is wrong, You must use relationship serializer.

prodName = ProductlistSerializer(many = False)

But I found Your model defintion is very confusing

Hayden
  • 449
  • 4
  • 13