Emma
Diverse decks of slide mainly about Django
By Emmanuelle Delescolle
In computer programming, an application programming interface (API) is [...] a set of clearly defined methods of communication among various components.
A good API makes it easier to develop a computer program by providing all the building blocks, which are then put together by the programmer.
An API may be for a web-based system, operating system, database system, computer hardware, or software library.
Source: Wikipedia
Endpoint base (/api/products/):
Item (/api/products/3/):
Searchable Dropdown
Web Frontend (Ember, Vue, React, ...)
Full-fledged client (GTK, mobile app, Java, ...)
Making data available to your users
Has become the de-facto standard for API's in the Django eco-system.
Had some success in the beginning, less so now.
Similar to other frameworks like Rails.
Its success was partially due to its fast prototyping abilities.
from restframework import viewsets, serializers
from .model import Product, Category
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name', 'category', 'in-stock')
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = ProductSerializer
queryset = Product.objects.all()
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name', 'products')
class CategoryViewSet(viewsets.ModelViewSet):
serializer_class = CategorySerializer
queryset = Category.objects.all()
from django.conf.urls import url, include
from rest_framework import routers
from catalog.api import ProductViewSet, CategoryViewSet
router routers.DefaultRouter()
router.register(ProductViewSet)
router.register(CategoryViewSet)
urlpatterns = [
...
url(r'^api/', include(router.urls)),
]
from tastypie.resources import ModelResource
from .models import Product, Category
class ProductResource(ModelResource):
class Meta:
queryset = Product.objects.all()
resource_name = 'product'
class CategoryResource(ModelResource):
class Meta:
queryset = Category.objects.all()
resource_name = 'category'
from django.conf.urls import url, include
from tastypie.api import Api
from myapp.api import ProductResource, CategoryResource
api = Api(api_name='myapi')
api.register(UserResource())
api.register(EntryResource())
urlpatterns = [
...
url(r'^api/', include(api.urls)),
]
from django.contrib import admin
from .models import Product, Category
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
pass
admin.site.register(Category)
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
...
]
from drf_auto_endpoint.router import router, register
from drf_auto_endpoint.endpoints import Endpoint
from .models import Product, Category
@register
class ProductEndpoint(Endpoint):
model = Product
router.register(Category)
from django.conf.urls import include, url
from drf_auto_endpoint.router import router
urlpatterns = [
url(r'^/api/', include(router.urls)),
...
]
from drf_auto_endpoint.endpoints import Endpoint
from .models import Product
class ProductEndpoint(Endpoint):
model = Product
filter_fields = ('category_id', )
search_fields = ('name', )
ordering_fields = ('in_stock', )
from drf_auto_endpoint import Endpoint
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs):
# do something fancy
return super(ProductViewSet, self) \
.create(request, *args, **kwargs)
class ProductEndpoint(Endpoint):
model = Product
base_viewset = ProductViewSet
base_serializer = ProductSerializer
from rest_framework import serializers
from drf_auto_endpoint.factories import serializer_factory
from .models import Category
class ProductSerializer(serializers.ModelSerializer):
category = serializer_factory(
model=Category,
['id', 'name', '__str__']
)(read_only=True)
from drf_auto_endpoint.endpoint import Endpoint
from drf_auto_endpoint.router import register, router
from .models import Product, Category
@register
class ProductEndpoint(Endpoint):
model = Product
filter_fields = ('category_id', )
search_fields = ('name', )
ordering_fields = ('in_stock', )
router.register(Category)
catalog/endpoints.py
from django.conf.urls import include, url
from drf_auto_endpoint.router import router
urlpatterns = [
...
url(r'^api/', include(router.urls)),
]
project/urls.py
INSTALLED_APPS = (
...
'drf_auto_endpoint',
)
settings.py
REST_FRAMEWORK = {
'DEFAULT_METADATA_CLASS': \
'drf_auto_endpoint.metadata.AutoMetadata',
}
DRF_AUTO_METADATA_ADAPTER = \
'drf_auto_endpoint.adapters.EmberAdapter'
settings.py
custom_actions = [
{
'type': 'modelMethod',
'method': 'makeDraft',
'icon_class': 'fa fa-fire',
'btn_class': 'btn btn-warning',
'text': 'Make draft',
'display_condition': {
'operator': 'eq',
'value': 'open',
'property_path': 'state',
},
}
]
@custom_action(method='POST', icon_class='fa fa-money', btn_class='btn btn-success', text='Pay',
pushPayload=True, allowBulk=True,
display_condition={'operator': 'eq', 'value': 'open', 'property_path': 'state', })
def pay(self, request, pk):
obj = get_object_or_404(self.model, pk=pk)
obj.state = 'paid'
obj.save()
serializer = self.get_serializer(obj)
rv = {}
rv[self.get_url()] = [serializer.data, ]
return Response(rv)
By Emma
DjangoCon Europe 2019 talk