Reputation: 3130
I'm trying to create a new object using Django REST Framework's ModelViewSet
and the ModelSerializer
and associate an existing object to it's ForeignKey
field. I have two models with a one-to-many relationship, basically a manufacturer and a product. The manufacturer already exists in the database and I'm trying to add a product individually and assign it's manufacturer at the same time. When I do, DRF is giving me this error:
"non_field_errors": [ "Invalid data. Expected a dictionary, but got Product." ]
Here are what my models look like (I've tried to take out the unneeded code to keep it small). When a product is created the manufacturer
field is an integer representing the ID of it's related object. As you can see in my view, I query for the Manufacturer
object, set it and then continue to let DRF create the object. If someone can please tell me where I'm going wrong, I'd greatly appreciate it!
models.py
class Manufacturer(models.Model):
name = models.CharField(max_length=64)
state = models.CharField(max_length=2)
class Product(models.Model):
manufacturer = models.ForeignKey(Manufacturer, related_name="products")
name = models.CharField(max_length=64)
sku = models.CharField(max_length=12)
views.py
class ProductViewSet(view sets.ModelViewSet):
model = Product
permission_classes = [IsAuthenticated]
def get_queryset(self):
# get logged in user's manufacturer
return Product.objects.filter(manufacturer=manufacturer)
def create(self, request, *args, **kwargs):
if "manufacturer" in request.data:
manufacturer = Manufacturer.objects.get(pk=request.data["manufacturer"])
request.data["manufacturer"] = manufacturer
return super(ProductViewSet, self).create(request, *args, **kwargs)
serializers.py
class ManufacturerSerializer(serializers.ModelSerializer):
class Meta:
model = Manufacturer
fields = ("id", "name", "state",)
read_only_fields = ("id",)
class ProductSerializer(serializers.ModelSerializer):
manufacturer = ManufacturerSerializer()
class Meta:
model = Product
fields = ("id", "manufacturer", "name",)
read_only_fields = ("id",)
Upvotes: 2
Views: 5222
Reputation: 3378
you have to set manufacturer_id
key.
change your serializer to:
class ProductSerializer(serializers.ModelSerializer):
manufacturer = ManufacturerSerializer(read_only=True)
manufacturer_id = serializers.IntegerField(write_only=True)
class Meta:
model = Product
fields = ("id", "manufacturer", "name",)
read_only_fields = ("id",)
change your create method to:
def create(self, request, *args, **kwargs):
if "manufacturer" in request.data:
request.data["manufacturer_id"] = request.data['manufacturer']
return super(ProductViewSet, self).create(request, *args, **kwargs)
Upvotes: 3