Django中的RESTful api在Django中使用inbult视图,无需创建2个url
Posted
技术标签:
【中文标题】Django中的RESTful api在Django中使用inbult视图,无需创建2个url【英文标题】:RESTful api in Django using inbult view in Django, without creating 2 urls 【发布时间】: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 方法,你建议什么。
【问题讨论】:
【参考方案1】:试试这个模式,这应该适用于两个网址 -
urlpatterns = patterns('',
(r'^invoices(/(?P<invoiceid>\d+)),1/$', views.InvoiceTransaction.as_view()),
)
这使得整个 id 块是可选的,但最多只能有一个。
顺便说一句,.*
不太适合 id,最好使用\d+
您可以在 pythex.org 上进行验证。
编辑: ^invoice(/(?P<invoice_type>.*)),1/$
【讨论】:
很好 :) 但是如果你能解释一下这个正则表达式会很棒,因为我对正则表达式不太满意,双小括号和大括号是如何工作的? 外括号是为了使整个块可选或最大 1(注意它后面的,1
),这允许invoice/
,如果块存在则invoice/10/
,因为最大1个可选块被支持invoice/10/5/
无效。
但^invoice(/(?P<invoice_type>.*)),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。所以,当我GET
ListCreateView
时,我得到了数据库中存在的所有发票的列表。当我 POST
到 ListCreateView
时,我应该能够在数据库的 Invoice
表中插入一个新条目。
现在,附加了 id 的 url。我们称之为RetrieveUpdateDeleteView
。顾名思义,视图应该能够执行三个功能,即RETRIEVE
、UPDATE
和DELETE
。并且所有这些操作都可以在已经存在的对象上执行,这些对象的 id 将出现在 url kwargs 中。
当我 GET
RetrieveUpdateDeleteView
时,我必须获取 url kwargs 中提供的 id
的对象。同样,PUT
和PATCH
应该使用用户发送的数据更新对象。而DELETE
应该从数据库中删除该对象。
这就是我规划REST
架构的方式。
【讨论】:
以上是关于Django中的RESTful api在Django中使用inbult视图,无需创建2个url的主要内容,如果未能解决你的问题,请参考以下文章
Django中CBV和Restful API中的APIView源码分析