Django REST çerçevesi: model olmayan serileştirici


158

Django REST çerçevesinde yeni başlıyorum ve tavsiyene ihtiyacım var. Bir web hizmeti geliştiriyorum. Hizmet, diğer hizmetlere REST arabirimi sağlamalıdır. Uygulamam gereken REST arayüzü, modellerimle doğrudan çalışmıyor (yani get, put, post, delete işlemleri). Bunun yerine, diğer hizmetlere bazı hesaplama sonuçları sağlar. Bir istek üzerine hizmetim bazı hesaplamalar yapar ve sadece sonuçları geri döndürür (sonuçları kendi veritabanında saklamaz).

Aşağıda bu REST arayüzünün nasıl uygulanabileceğine dair anlayışım var. Eğer Yanlışsam beni düzelt.

  1. Hesaplamaları yapan sınıf oluşturun. 'CalcClass' olarak adlandırın. CalcClass modelleri çalışmalarında kullanır.
    • Hesaplamalar için gerekli parametreler yapıcıya iletilir.
    • Kireç işlemini uygulayın. Sonuçları 'ResultClass' olarak döndürür.
  2. ResultClass oluşturun.
    • Nesneden türetilmiştir.
    • Sadece calc sonuçlarını içeren niteliklere sahiptir.
    • Kireç sonuçlarının bir kısmı, tuples tuples olarak temsil edilir. Anladığım kadarıyla, bu seriler için ayrı bir sınıf uygulamak ve bu nesnelerin ResultClass'a listesini eklemek daha fazla serileştirme için daha iyi olurdu.
  3. ResultClass için Serializer oluşturun.
    • Serileştiricilerden türetin.
    • Calc sonuçları salt okunurdur, bu nedenle IntegerField gibi özel sınıflar yerine alanlar için çoğunlukla Field sınıfını kullanın.
    • Ben sonuçları depolamak değil çünkü ben sadece ResultClass ne de Serializer üzerinde save () yöntemi impl olmamalıdır (Ben sadece istek üzerine onları iade etmek istiyorum).
    • İç içe geçmiş sonuçlar için serileştirici ekleyin (yukarıda belirtilen tuples demetini unutmayın).
  4. Hesaplama sonuçlarını döndürmek için Görünüm oluştur.
    • APIView'den türetilmiştir.
    • Sadece ().
    • Get () 'de, istekten alınan parametrelerle CalcClass'ı yaratın, calc () öğesini çağırın, ResultClass'ı alın, Serializer oluşturun ve ResultClass'ı ona iletin, Response (serializer.data) döndürün.
  5. URL'ler
    • Benim durumumda api kökü yok. Sadece çeşitli kireç sonuçları (fark parametreleri ile kireç) almak için URL'lerim olmalıdır.
    • Api taraması için çağrı biçimi_suffix_patterns ekleyin.

Bir şey mi kaçırdım? Yaklaşım genel olarak doğru mu?


Bu yaklaşım doğrudur ve benim için aslında kabul edilen yanıttan daha zarif görünüyor (yeniden kullanılabilir sonuç türünde kapsüllenmiş sonuç verileri). Ancak günün sonunda bu çoğunlukla kişisel tercih meselesidir ve her iki yaklaşım da işi yapar.
zepp.lee

Yanıtlar:


157

Django-rest-framework bir modele bağlamadan bile iyi çalışır. Yaklaşımınız iyi görünüyor, ancak her şeyin işe yaraması için bazı adımları kesebileceğinize inanıyorum.

Örneğin, dinlenme çerçevesi birkaç yerleşik oluşturucu ile birlikte gelir. Kutunun dışında JSON ve XML'i API tüketicisine döndürebilir. YAML'yi yalnızca gerekli python modülünü yükleyerek de etkinleştirebilirsiniz. Django-rest-framework, dict, list ve tuple gibi herhangi bir temel nesneyi, herhangi bir ekstra iş yapmadan çıkarır.

Yani temelde sadece argümanları alan, gerekli tüm hesaplamaları yapan ve sonuçlarını bir demet halinde REST api görünümüne döndüren bir fonksiyon veya sınıf yaratmanız gerekir. JSON ve / veya XML ihtiyaçlarınızı karşılarsa, django-rest-framework serileştirmeyi sizin için halleder.

Bu durumda 2. ve 3. adımları atlayabilir ve yalnızca hesaplamalar için bir sınıf ve API tüketicisine sunum için bir sınıf kullanabilirsiniz.

İşte size yardımcı olabilecek birkaç parçacık:

Lütfen bunu test etmediğimi unutmayın. Sadece örnek olması gerekiyordu, ama işe yaramalı :)

CalcClass:

class CalcClass(object):

    def __init__(self, *args, **kw):
        # Initialize any variables you need from the input you get
        pass

    def do_work(self):
        # Do some calculations here
        # returns a tuple ((1,2,3, ), (4,5,6,))
        result = ((1,2,3, ), (4,5,6,)) # final result
        return result

REST görünümü:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from MyProject.MyApp import CalcClass


class MyRESTView(APIView):

    def get(self, request, *args, **kw):
        # Process any get params that you may need
        # If you don't need to process get params,
        # you can skip this part
        get_arg1 = request.GET.get('arg1', None)
        get_arg2 = request.GET.get('arg2', None)

        # Any URL parameters get passed in **kw
        myClass = CalcClass(get_arg1, get_arg2, *args, **kw)
        result = myClass.do_work()
        response = Response(result, status=status.HTTP_200_OK)
        return response

Urls.py:

from MyProject.MyApp.views import MyRESTView
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    # this URL passes resource_id in **kw to MyRESTView
    url(r'^api/v1.0/resource/(?P<resource_id>\d+)[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
    url(r'^api/v1.0/resource[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
)

Bu kod, http://example.com/api/v1.0/resource/?format=json adresine eriştiğinizde bir liste listesi çıkarmalıdır . Bir eki kullanıyorsanız, yerini alabilir ?format=jsonile .json. Üstbilgilere "Content-type"veya ekleyerek geri almak istediğiniz kodlamayı da belirtebilirsiniz "Accept".

[
  [
    1, 
    2, 
    3
  ], 
  [
    4, 
    5, 
    6
  ]
]

Umarım bu size yardımcı olur.


2
Merhaba Gabriel! Cevabınız için teşekkür ederim! Planıma göre ihtiyacım olanı zaten uyguladım. İyi çalışıyor! Daha iyi json çıkışı için serileştiriciyi kullandım.
Zakhar

3
Bu öneriyi takip etmeye çalıştım ama şunu elde ederim: "DjangoModelPermissions .modelveya .querysetözelliği olmayan bir görünümde uygulanamıyor .". Verilen tam örneği denedim. Django-rest-framework'ün son sürümüyle ilgili bir şey olabilir mi?
Orlando

Bu örnek bir süre önce yazılmıştır. O zamandan beri tekrar Django ile çalışma şansım olmadı. ancak burada yararlı bir şeyler bulabilirsiniz: django-rest-framework.org/api-guide/routers
Gabriel Samfira

1
Bu örnek tam olarak ihtiyacım olan şey, model olmayan bir seri hale getirici olmadan bazı işlemler yapan bir hizmettir!
Khalil TABBAL

@Orlando: djang-restframework 3 ile model olmayan bir görünüme özgü izin mantığının nasıl uygulanacağına bir göz atın: stackoverflow.com/a/34040070/640916
djangonaut

-1

Urls.py dosyasında login_required işlevi gerektirir

from django.contrib.auth.decorators import login_required

bu cevap yerine yalnızca bir yorumsa, add a comment
yorumsa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.