RESTful api 在 Django 中使用 Django 中的 inbult 视图,无需创建 2 个 url

RESTful api in Django using inbult view in Django, without creating 2 urls

我在 Django 中基于函数的视图方面有丰富的经验,现在我正在尝试使用基于 Class 的视图。虽然我能够解决问题,但我不确定标准,我的意思是,如果我做对或错,你们 guyz(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 文件中为单个请求创建了两行(url)以确定 GET 请求的类型。有没有其他或更好的方法来做到这一点。如何在不创建 2 个网址的情况下使用视图创建 restful api。

PS:请随意在上面的代码中建议 improvement/changes,因为我是这方面的新手。可能是我错误地使用了 dispatch 方法,或者我真的不需要 init 方法,任何你建议的。

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

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

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

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

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

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

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

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

编辑:^invoice(/(?P<invoice_type>.*)){,1}/$

正如 REST 所述,系统必须仅根据名词和动词进行交流。

适用于 RESTful 架构的动词是:

GET
POST
PUT
PATCH
DELETE

和 2 urls,RESTful 系统的任何资源表示是:

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

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

您可以 edit/delete 只有现有对象,并且数据库中的所有现有对象都应该有一个与之关联的 ID。因此,当我 GET ListCreateView 时,我得到了数据库中所有现有发票的列表。当我 POSTListCreateView 时,我应该能够在数据库的 Invoice table 中插入一个新条目。

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

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

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