Подтвердить что ты не робот

Как я могу зарегистрировать одно представление (а не viewet) на моем маршрутизаторе?

Я использую структуру Django REST и пытаюсь создать представление, которое возвращает небольшой бит информации, а также регистрирует его на моем маршрутизаторе.

У меня есть четыре модели, которые хранят информацию, и все они имеют поле created_time. Я пытаюсь сделать представление, которое возвращает самые последние объекты (на основе created_time) в одном представлении, где возвращаются только четыре времени создания.

Итак, возможный вывод JSON из представления будет выглядеть как

{
    "publish_updatetime": "2015.05.20 11:53",
    "meeting_updatetime": "2015.05.20 11:32",
    "training_updatetime": "2015.05.20 15:25",
    "exhibiting_updatetime": "2015.05.19 16:23"
}

Я также надеюсь зарегистрировать это представление на моем маршрутизаторе, поэтому он появляется вместе с остальными моими конечными точками при загрузке корня API.

router.register(r'updatetime', views.UpdateTimeView)

Вот четыре модели, которые я пытаюсь работать с

class Publish(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    created_time = models.DateTimeField( default=datetime.now)

class Meeting(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    file_addr = models.FileField(upload_to=get_file_path)
    created_time = models.DateTimeField(default=datetime.now)

class Training(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to=get_file_path, max_length=255)
    created_time = models.DateTimeField(default=datetime.now)

class Exhibiting(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    file_addr = models.FileField(upload_to=get_file_path)
    created_time = models.DateTimeField(default=datetime.now)

Можно ли это сделать? И как это будет сделано?

4b9b3361

Ответ 1

Маршрутизаторы работают с ViewSet и не предназначены для обычных представлений, но это не означает, что вы не можете использовать их с обычным представлением. Обычно они используются с моделями (и a ModelViewSet), но их можно использовать без них с помощью GenericViewSet (если вы обычно используете GenericAPIView) и ViewSet (если вы просто используете APIView).

Для представления списка методы запроса сопоставляются с методами ViewSet, такими как

  • GETlist(self, request, format=None)
  • POSTcreate(self, request, format=None)

Для подробных представлений (с первичным ключом в URL-адресе) методы запроса используют следующую карту

  • GETretrieve(self, request, pk, format=None)
  • PUTupdate(self, request, pk, format=None)
  • PATCHpartial_update(self, request, pk, format=None)
  • DELETEdestroy(self, request, pk, format=None)

Итак, если вы хотите использовать любой из этих методов запроса с вашим представлением на своем маршрутизаторе, вам необходимо переопределить правильный метод просмотра (так что list() вместо get()).


Теперь, особенно в вашем случае, вы обычно использовали бы APIView, который выглядел бы как

class UpdateTimeView(APIView):

    def get(self, request, format=None):
        latest_publish = Publish.objects.latest('created_time')
        latest_meeting = Meeting.objects.latest('created_time')
        latest_training = Training.objects.latest('created_time')
        latest_exhibiting = Exhibiting.objects.latest('created_time')

        return Response({
            "publish_updatetime": latest_publish.created_time,
            "meeting_updatetime": latest_meeting.created_time,
            "training_updatetime": latest_training.created_time,
            "exhibiting_updatetime": latest_exhibiting.created_time,
        })

Сопоставимый ViewSet будет

class UpdateTimeViewSet(ViewSet):

    def list(self, request, format=None):
        latest_publish = Publish.objects.latest('created_time')
        latest_meeting = Meeting.objects.latest('created_time')
        latest_training = Training.objects.latest('created_time')
        latest_exhibiting = Exhibiting.objects.latest('created_time')

        return Response({
            "publish_updatetime": latest_publish.created_time,
            "meeting_updatetime": latest_meeting.created_time,
            "training_updatetime": latest_training.created_time,
            "exhibiting_updatetime": latest_exhibiting.created_time,
        })

Обратите внимание на два требуемых изменения: APIViewViewSet и GETlist. Я также обновил имя, указав, что это не просто нормальный вид (поскольку ViewSet не может быть инициализирован таким же образом), но это не требуется.

Таким образом, с помощью этого нового представления вы можете просто зарегистрировать его в маршрутизаторе так же, как и любой другой. Вам нужно base_name здесь, чтобы имена url могли быть сгенерированы (обычно это вытаскивало из запроса).

router.register(r'updatetime', views.UpdateTimeViewSet, base_name='updatetime')

Итак, конечная точка updatetime будет доступна в корне API, и вы сможете получить последние времена, просто вызвав конечную точку (простой запрос GET).

Ответ 2

Есть еще один способ сделать это:

urlpatterns = [
    # ... 
    url(r'^you_path/', include(router.urls)),
    url(r'^you_path/you_sub_path', views.UpdateTimeView.as_view()),
    # ... 
]

Но такие вещи, как Swagger, не будут работать с этим