【问题标题】:RESTful api in Django using inbult view in Django, without creating 2 urlsDjango中的RESTful api在Django中使用inbult视图,无需创建2个url
【发布时间】:2015-11-01 14:01:01
【问题描述】:

我在 Django 中基于函数的视图方面拥有不错的经验,现在我正在尝试使用基于类的视图。虽然我能够解决问题,但我不确定标准,我的意思是如果我做的对或错,你们(Django 开发人员)遵循什么。

关于问题的更多细节在这里-

views.py

from django.views.generic import View

class InvoiceTransaction(View):

    def __init__(self):
        super(InvoiceTransaction, self).__init__()

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(InvoiceTransaction, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        invoiceid = kwargs.get('invoiceid')
        # here I have invoiceid, which is I'm passing through url paramaeters(see urls.py file)
        # based on invoice, I can decide what type of GET requests it is
        # whether user is asking for a single resource or all resource, right?
        if invoiceid:
             invoice = [Invoice.objects.get(id=invoiceid)]
        else:
             invoice = Invoice.objects.all()

    def post(self, request, *args, **kwargs):
        # some stuff 

urls.py

from django.conf.urls import patterns, url
from invoice import views

urlpatterns = patterns('',
    (r'^invoices/$', views.InvoiceTransaction.as_view()),
    (r'^invoices/(?P<invoiceid>.*)/$', views.InvoiceTransaction.as_view()),
)

我按照这个教程https://realpython.com/blog/python/django-rest-framework-class-based-views/

所以我的问题是我在 urls.py 文件中为单个请求创建了两行(urls)以确定 GET 请求的类型。有没有其他或更好的方法来做到这一点。如何使用视图而不创建 2 个 url 创建一个宁静的 api。

PS:请随意建议对上述代码的改进/更改,因为我是这个东西的新手。可能是我错误地使用了 dispatch 方法,或者真的不需要 init 方法,你建议什么。

【问题讨论】:

    标签: python django django-views django-urls django-class-based-views


    【解决方案1】:

    试试这个模式,这应该适用于两个网址 -

    urlpatterns = patterns('',
        (r'^invoices(/(?P<invoiceid>\d+)){,1}/$', views.InvoiceTransaction.as_view()),
    )
    

    这使得整个 id 块是可选的,但最多只能有一个。

    顺便说一句,.* 不太适合 id,最好使用\d+

    您可以在 pythex.org 上进行验证。

    编辑: ^invoice(/(?P&lt;invoice_type&gt;.*)){,1}/$

    【讨论】:

    • 很好 :) 但是如果你能解释一下这个正则表达式会很棒,因为我对正则表达式不太满意,双小括号和大括号是如何工作的?
    • 外括号是为了使整个块可选或最大 1(注意它后面的{,1}),这允许invoice/,如果块存在则invoice/10/,因为最大1个可选块被支持invoice/10/5/无效。
    • ^invoice(/(?P&lt;invoice_type&gt;.*)){,1}/$ 不起作用?你能建议这有什么问题吗? invoice_type 是一个字符串(在我看来将与预定义的单词匹配)
    • 谁说不工作?我为它添加了另一个屏幕截图。看看吧。
    • invalid literal for int() with base 10: '' 我在制作这种 url 模式时得到了这个,对于你在答案中写的那个。可能是什么原因。如果我使用 POSTMAN 或其他一些 API 模拟器点击这个 url 它可以工作,但是 django 管理面板没有打开并抛出错误
    【解决方案2】:

    您只需删除第一个模式并从第二个模式中删除结束斜线。
    所以,你的 urlpatterns 变成了

    urlpatterns = patterns('',
        (r'^invoices/(?P<invoiceid>.*)$', views.InvoiceTransaction.as_view()),
    )
    

    这是因为您已经在正则表达式中使用 .* 而不是 .+,您收到的 invoiceid 可以为空。
    但是你的正则表达式中的强制结束斜线阻止了这种情况的发生。简单来说,您已经找到了问题的解决方案。

    【讨论】:

      【解决方案3】:

      正如 REST 规定的那样,系统只能用名词和动词来说话。

      适用于 RESTful 架构的动词有:

      GET
      POST
      PUT
      PATCH
      DELETE
      

      还有 2 个 url,RESTful 系统的任何资源表示是:

      invoice/$
      invoice/(?P<pk>\d+)/$
      

      让我们看看处理没有 pk 的 url 的视图。让我们将此视图称为 InvoiceListCreateView。现在,InvoiceListCreateView 应该只满足 GET 和 POST 请求。它不应该允许PUT, PATCH and DELETE 请求。为什么?

      您只能编辑/删除现有对象,并且数据库中的所有现有对象都应该有一个与之关联的 id。所以,当我GETListCreateView 时,我得到了数据库中存在的所有发票的列表。当我 POSTListCreateView 时,我应该能够在数据库的 Invoice 表中插入一个新条目。

      现在,附加了 id 的 url。我们称之为RetrieveUpdateDeleteView。顾名思义,视图应该能够执行三个功能,即RETRIEVEUPDATEDELETE。并且所有这些操作都可以在已经存在的对象上执行,这些对象的 id 将出现在 url kwargs 中。

      当我 GET RetrieveUpdateDeleteView 时,我必须获取 url kwargs 中提供的 id 的对象。同样,PUTPATCH 应该使用用户发送的数据更新对象。而DELETE 应该从数据库中删除该对象。

      这就是我规划REST 架构的方式。

      【讨论】:

        猜你喜欢
        • 2019-11-19
        • 2020-05-12
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2016-05-13
        • 1970-01-01
        • 2013-08-08
        • 2021-07-24
        相关资源
        最近更新 更多