【问题标题】:Django REST Framework: Use of 'pk' in get_object_or_404Django REST 框架:在 get_object_or_404 中使用“pk”
【发布时间】:2021-09-04 08:56:25
【问题描述】:

我是 Django REST 框架的初学者,我正在构建一个应用程序来总结带有标题的文章。我试图从Article 模型中获取信息以传递到Summary 之一。我无法理解在这种情况下使用get_object_or_404(如何实例化模型)以及如何使用pk 参数。我尝试将status URL 更改为status/<int:article_id> 并将article 作为pk 传递,但是在运行POST 请求时我得到了404。我被困在如何使用该论点上。如何正确使用 get_object_or_404 从我的请求中实例化模型?

views.py

import json
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, JsonResponse
from rest_framework.decorators import api_view
from .models import *


@api_view(['POST'])
def get_summary(request, pk):
    article = get_object_or_404(Article, pk=pk)
    mdl = Summary()
    return JsonResponse(mdl.preprocess(article.content), safe=False)

models.py

# Article class
class Article(models.Model):
    headings = models.CharField(max_length=200)
    content = models.CharField(max_length=500000)


# Summary results class (so far)
class Summary(models.Model):
    preprocessor = TextPreprocessor()
    in_text = models.CharField(max_length=500000)
    topics = models.CharField(max_length=200)

    def preprocess(self, text):
        return self.preprocessor.preprocess(text)

urls.py

from django.urls import path, include
from rest_framework import routers
from .api import *
from .views import *

router = routers.DefaultRouter()
router.register('my_api', SummaryViewSet, 'api')

urlpatterns = [
    path('api/', include(router.urls)),
    path('status/', get_summary)
]

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    get_object_or_404 结果在名称中。如果找不到对象,这将引发错误。因此,您在视图中获得了 404,这是因为该对象尚不存在。您可能会将此与 get_or_create 混淆。我将向您展示一个使用基于函数的视图的解决方案。

    https://www.django-rest-framework.org/api-guide/views/

    https://www.django-rest-framework.org/tutorial/2-requests-and-responses/

    @api_view(['GET','POST'])
    def get_summary(request, pk):
        mdl = Summary()
        if request.method == 'GET':
            article = get_object_or_404(Article, pk=pk)
            return JsonResponse(mdl.preprocess(article.content), safe=False)
        # this will run on POST
        article = Article()
        article.heading, article.content = request.data['heading'], request.POST['content']
        article.save()
        return JsonResponse(mdl.preprocess(article.content), safe=False)
    

    =============================

    您可能会从使用 CBV 中受益

    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class GetSummary(APIView):
        
        def get(self, request, pk):
            ..run get logic above..
            return Response(..any data from serialer or even a string)
      
        def post(self, request, pk):
            ...run post logic above
    

    另外,只需将内容的模型属性设置为像这样的文本字段..

    models.py

    class Article(models.Model):
        headings = models.CharField(max_length=200)
        content = models.TextField()
    

    【讨论】:

    • 这里使用 request.data['content'] 和 request.POST['content'] 有什么区别?前者出于某种原因只对我有用
    • 基本上 request.data 更灵活,无论如何文档实际上都推荐用于 Django Rest。我将更新我的答案以使用 request.data。 stackoverflow.com/questions/28545553/…
    • 好的,知道了。我也根本不需要 GET 请求来检索这些数据吗?
    • 如果可行,请不要忘记接受答案。哦,现在,您的装饰器已将此视图设置为仅接受 POST 请求。如果您尝试执行 GET,则会导致错误。所以这个端点只接受 POST,这里的逻辑是每次都在更新实例。此时,在添加 api_view(['GET', 'POST"]) 之后,您必须在视图中构建逻辑。就像 request.method == 'GET' ...做这样那样..如果您也打算为此端点允许 GET,我可以添加它
    • 好的,接受。是的,我认为允许 GET 会更好,但我不确定这样做的逻辑是什么(我想我只想将每个实例保存在我的数据库中)
    猜你喜欢
    • 2018-12-09
    • 1970-01-01
    • 2019-04-08
    • 2016-08-01
    • 2018-03-30
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2020-04-13
    相关资源
    最近更新 更多