I have a model that uses the django content type framework
class Foo(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT)
object_id = models.UUIDField()
contentObject = GenericForeignKey()
then I use the modelViewSet and the serializer
class FooViewSet(viewsets.ModelViewSet):
serializer_class = FooSerializer
queryset = Foo.objects.all()
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
fields = ('__all__')
how can I create data using POST to the viewSet?
I arbitrary tried POST the object id from another model to content_type
, object_id
, and content_object
then I got the error "Incorrect type. Expected pk value, received str."
I already look in http://www.django-rest-framework.org/api-guide/relations/#generic-relationships or look in stack overflow but can't find any about how to POST the data, maybe my search wasn't thorough enough, I'm sorry. Thanks for checking out my question
UPDATE
I tried to override the create method in serializer:
I try to get the ContentType object from get_for_model
method, but it return AttributeError: 'AnotherModelX' object has no attribute 'replace'
def create(self, validated_data):
content_type = validated_data.get("object_id")
taggedObject = AnotherObject1.objects.get(id=content_type) if AnotherObject1.objects.filter(id=content_type).count() > 0 else None
taggedObject = AnotherObject2.objects.get(id=content_type) if AnotherObject2.objects.filter(id=content_type).count() > 0 and taggedObject == None else None
if taggedObject is not None:
contentType = ContentType.objects.get_for_model(taggedObject)
if contentType is not None:
validated_data["content_type"] = contentType
validated_data["object_id"] = taggedObject
return super(FooSerializer, self).create(validated_data)
class Meta:
model = Foo
fields = ('__all__')
extra_kwargs = {
'content_type': {'required': False},
Turns out my last update was close to the solution,
it should be assigning an id in the validated_data["object_id]
then it works. Here are the POST json data to Foo
:
{
"object_id": <<another_model_uuid>>
}
Be sure to get all the possible model so taggedObject
contains the instance of a model.
It is now solved then, thank you!
Bellow is the correct create
method in serializer
def create(self, validated_data):
content_type = validated_data.get("object_id")
taggedObject = AnotherObject1.objects.get(id=content_type) if AnotherObject1.objects.filter(id=content_type).count() > 0 else None
taggedObject = AnotherObject2.objects.get(id=content_type) if AnotherObject2.objects.filter(id=content_type).count() > 0 and taggedObject == None else None
if taggedObject is not None:
contentType = ContentType.objects.get_for_model(taggedObject)
if contentType is not None:
validated_data["content_type"] = contentType
validated_data["object_id"] = taggedObject.id
return super(FooSerializer, self).create(validated_data)