Django Rest Framework - выполнить запрос Put, передавая объект JSON вместо просто ID - PullRequest
0 голосов
/ 18 февраля 2019

Я работаю над проектом, использующим Python (3), Django (1.11) и DRF (3.6), в котором я должен выполнить запрос PUT, передав nested nested вместо ID.

Вот что я пробовал:

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)

Обновление: Здесь, когда я отправляю запрос на публикацию со следующим объектом:

{
  "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"
}

, эта ошибка возвращается как: 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"
}

Требования: Обновление URL-адреса аватара actor: Служба должна иметь возможность обновлять URL-адрес аватара субъекта по запросу PUT на /actors.Актер JSON отправляется в теле запроса.Если субъект с идентификатором не существует, тогда код ответа должен быть 404, или если для субъекта обновляются другие поля, тогда код ответа HTTP должен быть 400, в противном случае код ответа должен быть * 1052.*. **

Я немного озадачен тем, как выполнить запрос PUT без передачи ID?

1 Ответ

0 голосов
/ 18 февраля 2019

Я видел твои два-три вопроса, которые задавали сегодня.Я думаю, что вы задаете неправильный вопрос.Я думаю, что вам нужно три модели Event, actor и repo.модель event имеет два поля внешнего ключа: actor и repo.Теперь вы хотите обновить поле actor models avtar_url.ОК?

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()

Теперь для создания и обновления записи NESTED EventModel используйте writable-nested-serializer .Таким образом, вы можете напрямую обновить avatar_url для Actor по его идентификатору.

ОБНОВЛЕНИЕ согласно запросу

вам нужно изменить метод create следующим образом, чтобы он создавал Actor, Repo и связывал их идентификаторы с 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)
...