0

I'm working on a Project using Python(3), Django(1.11) and DRF(3.6) in which I have to perform a PUT request by passing a nested nested instead of an ID.

Here's What I have tried:

models.py:

class Actor(models.Model):
    id = models.CharField(primary_key=True, max_length=255)
    login = models.CharField(max_length=255)
    avatar_url = models.URLField(max_length=500)


class Repo(models.Model):
    id = models.CharField(primary_key=True, max_length=255)
    name = models.CharField(max_length=255)
    url = models.URLField(max_length=500)


class Event(models.Model):
    id = models.CharField(primary_key=True, max_length=255)
    type = models.CharField(max_length=255)
    actor = models.ForeignKey(Actor, related_name='actor')
    repo = models.ForeignKey(Repo, related_name='repo')
    created_at = models.DateTimeField()

serializers.py:

class ActorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Actor
        fields = ('id', 'login', 'avatar_url')


class RepoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Repo
        fields = ('id', 'name', 'url')


class EventModelSerializer(serializers.ModelSerializer):
    actor = ActorSerializer(many=False)
    repo = RepoSerializer(many=False)

    class Meta:
        model = Event
        fields = ('id', 'type', 'actor', 'repo', 'created_at')
        depth = 1

    def create(self, validated_data):
        return Event.objects.create(**validated_data)

Update: Here when I submit a post request with the following object:

{
  "id":ID,
  "type":"PushEvent",
  "actor":{
    "id":ID,
    "login":"daniel33",
    "avatar_url":"https://avatars.com/2790311"
  },
  "repo":{
    "id":ID,
    "name":"johnbolton/exercitationem",
    "url":"https://github.com/johnbolton/exercitationem"
  },
  "created_at":"2015-10-03 06:13:31"
}

it return this error as: TypeError: 'ValueError: Cannot assign "OrderedDict([('id', '2790311'), ('login', 'daniel33'), ('avatar_url', 'https://avatars.com/2790311')])": "Event.actor" must be a "Actor" instance.

views.py:

class Actor(generics.GenericAPIView):
    serializer_class = EventModelSerializer
    queryset = EventModel.objects.all()

    def update(self):
        actor = EventModel.objects.filter(actor_id=self.request.data('id'))
        print(actor)
        return HttpResponse(actor)

Sample Input Object:

{
  "id":3648056,
  "login":"ysims",
  "avatar_url":"https://avatars.com/modified2"
}

The requirements is: Updating the avatar URL of the actor: The service should be able to update the avatar URL of the actor by the PUT request at /actors. The actor JSON is sent in the request body. If the actor with the id does not exist then the response code should be 404, or if there are other fields being updated for the actor then the HTTP response code should be 400, otherwise, the response code should be 200.**

I'm little bit confused about how to perform the PUT request without passing an ID?

Abdul Rehman
  • 5,326
  • 9
  • 77
  • 150

1 Answers1

0

I have seen your two-three questions asked today. I think You are asking the wrong question. I think what you need is three models Event, actor and repo. the event model has two foreign key fields as actor and repo. Now what you want it to update the actor models avtar_url field. OK?

class Actor(models.Model):
        avtar_url = models.CharField(max_length=255)
       # Other Fields

class Repo(models.Model):
       # Other Fields

class EventModel(models.Model):
        id = models.CharField(primary_key=True, max_length=255)
        type = models.CharField(max_length=255)
        actor = models.ForaignKey(Actor)
        repo = models.ForaignKey(Actor)
        created_at = models.DateTimeField()

Now for create and update the NESTED EventModel entry use writable-nested-serializers. By this, you can directly update the avatar_url for Actor by its id.

UPDATE as per Request

you need to change your create method as following so that it creates Actor, Repo and link their ids to Event

def create(self, validated_data):
        actor = validated_data.pop('actor')
        repo = validated_data.pop('repo')
        actor = Actor.objects.create(**actor)
        repo = Repo.objects.create(**repo)
        return Event.objects.create(actor=actor,repo=repo,**validated_data)
Ashwin Bande
  • 2,693
  • 2
  • 10
  • 22
  • Hi @ashwin bande, I have updated my `models` and `serializers` but there another error comes in, how do I need to change my `serializers`? – Abdul Rehman Feb 18 '19 at 15:09
  • now it returns `{ "actor": [ "Invalid pk \"{'id': 2790311, 'login': 'daniel33', 'avatar_url': 'https://avatars.com/2790311'}\" - object does not exist." ], "repo": [ "Invalid pk \"{'id': 352806, 'name': 'johnbolton/exercitationem', 'url': 'https://github.com/johnbolton/exercitationem'}\" - object does not exist." ] }` – Abdul Rehman Feb 18 '19 at 15:34
  • I got it, there was a typo on my end. – Abdul Rehman Feb 18 '19 at 15:36
  • SO is it working? if so Mark the answer as accepted so that others will know it is a working solution. – Ashwin Bande Feb 18 '19 at 15:38
  • I stuck on the `update` method, how can I define the update? – Abdul Rehman Feb 18 '19 at 15:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188612/discussion-between-ashwin-bande-and-abdul-rehman). – Ashwin Bande Feb 18 '19 at 15:39