from django.db import models
class Meal(models.Model):
owner = models.ForeignKey('auth.User', related_name='meals')
name = models.CharField(max_length=255)
notes = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
from rest_framework import serializers
from .models import Meal
class MealSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.Field(source='owner.username')
class Meta:
model = Meal
fields = ('url', 'owner', 'name', 'notes')
Third party packages (MongoEngineModelSerializer, GeoFeatureModelSerializer, HStoreSerializer)
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Meal
from .serializers import MealSerializer
@api_view(['GET', 'POST'])
def meal_list(request):
if request.method == 'GET':
meal = Meal.objects.all()
serializer = MealSerializer(meal, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = MealSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout.
— RFC 2324, Hyper Text Coffee Pot Control Protocol
418
I'm a teapot
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Meal
from .serializers import MealSerializer
class MealList(APIView):
def get(self, request, format=None):
meal = Meal.objects.all()
serializer = MealSerializer(meal, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MealSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
from rest_framework import mixins
from rest_framework import generics
from .models import Meal
from .serializers import MealSerializer
class MealList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Meal.objects.all()
serializer_class = MealSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
from rest_framework import generics
from .models import Meal
from .serializers import MealSerializer
class MealList(generics.ListCreateAPIView):
queryset = Meal.objects.all()
serializer_class = MealSerializer
from rest_framework import viewsets
from .models import Meal
from .serializers import MealSerializer
class MealViewSet(viewsets.ModelViewSet):
queryset = Meal.objects.all()
serializer_class = MealSerializer
from rest_framework.routers import DefaultRouter
from .views import MealViewSet
router = DefaultRouter()
router.register(r'meal', MealViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
]
from rest_framework import permissions, viewsets
from .permissions import IsOwner
class MealViewSet(viewsets.ModelViewSet):
queryset = Meal.objects.all()
serializer_class = MealSerializer
permission_classes = (permissions.IsAuthenticated, IsOwner,)
def pre_save(self, obj):
obj.owner = self.request.user
from rest_framework import permissions
class IsOwner(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to view
and edit it.
"""
def has_object_permission(self, request, view, obj):
return obj.owner == request.user
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
BasicAuthentication
TokenAuthentication
SessionAuthentication
OAuthAuthentication
OAuth2Authentication
Digest Authentication
Django OAuth Toolkit
Django OAuth2 Consumer
JSON Web Token Authentication
Hawk HTTP Authentication
HTTP Signature Authentication
Code without tests is broken as designed.
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from .models import Meal
class MealViewTest(APITestCase):
def test_add_meal_will_save_the_owner(self):
user_name, user_password, user = create_user()
user_auth(self.client, user_name, user_password)
data = {'name': 'new meal'}
response = self.client.post(
reverse('meal-list'), data, format='json'
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(response.data['owner'], 'john')
def create_user():
user_name = 'john'
user_email = 'lennon@thebeatles.com'
user_password = 'johnpassword'
user = User.objects.create_user(user_name, user_email, user_password)
return user_name, user_password, user
def user_auth(api_client, user_name, user_password):
api_client.login(username=user_name, password=user_password)
https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
https://github.com/ottoyiu/django-cors-headers
RestangularProvider.setDefaultHeaders({"X-CSRFToken": csrftoken});
$http.defaults.headers.common["X-CSRFToken"] = csrftoken;