From 3e4c70237fbecf97cb54979062bcfb61da4d6d50 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Sat, 3 Mar 2018 14:24:57 +0100 Subject: [PATCH] Working API --- Pipfile | 1 + Pipfile.lock | 9 +++++- gym/migrations/0002_auto_20180303_1201.py | 38 +++++++++++++++++++++++ gym/models.py | 10 +++--- gym/serializers.py | 22 +++++++++++++ gym/urls.py | 21 +++++++++++++ gym/views.py | 25 +++++++++++++-- muscu/settings.py | 22 ++++++++----- muscu/urls.py | 4 ++- 9 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 gym/migrations/0002_auto_20180303_1201.py create mode 100644 gym/serializers.py create mode 100644 gym/urls.py diff --git a/Pipfile b/Pipfile index 9f107c9..6f1b3be 100644 --- a/Pipfile +++ b/Pipfile @@ -8,6 +8,7 @@ name = "pypi" [packages] django = "*" +djangorestframework = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 95ee55c..9c5b5e3 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8b5635a4f7b069ae6661115b9eaa15466f7cd96794af5d131735a3638be101fb" + "sha256": "1f3d4cc7027911c0d5599450f18f080ccf209827c665920bad7fc6e832bb3b38" }, "host-environment-markers": { "implementation_name": "cpython", @@ -34,6 +34,13 @@ ], "version": "==2.0.2" }, + "djangorestframework": { + "hashes": [ + "sha256:1f6baf40ed456ed2af6bd1a4ff8bbc3503cebea16509993aea2b7085bc097766", + "sha256:9f9e94e8d22b100ed3a43cee8c47a7ff7b185e778a1f2da9ec5c73fc4e081b87" + ], + "version": "==3.7.7" + }, "pytz": { "hashes": [ "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", diff --git a/gym/migrations/0002_auto_20180303_1201.py b/gym/migrations/0002_auto_20180303_1201.py new file mode 100644 index 0000000..a764840 --- /dev/null +++ b/gym/migrations/0002_auto_20180303_1201.py @@ -0,0 +1,38 @@ +# Generated by Django 2.0.2 on 2018-03-03 11:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gym', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='room', + name='latitude', + field=models.DecimalField(blank=True, decimal_places=8, max_digits=11, verbose_name='latitude'), + ), + migrations.AlterField( + model_name='room', + name='longitude', + field=models.DecimalField(blank=True, decimal_places=8, max_digits=11, verbose_name='longitude'), + ), + migrations.AlterField( + model_name='room', + name='notes', + field=models.TextField(blank=True, verbose_name='notes'), + ), + migrations.AlterField( + model_name='round', + name='notes', + field=models.TextField(blank=True, verbose_name='notes'), + ), + migrations.AlterField( + model_name='session', + name='notes', + field=models.TextField(blank=True, verbose_name='notes'), + ), + ] diff --git a/gym/models.py b/gym/models.py index d501231..991980b 100644 --- a/gym/models.py +++ b/gym/models.py @@ -7,9 +7,9 @@ class Room(models.Model): verbose_name_plural = 'salles' name = models.CharField('nom', max_length=300) - latitude = models.DecimalField('latitude', max_digits=11, decimal_places=8) - longitude = models.DecimalField('longitude', max_digits=11, decimal_places=8) - notes = models.TextField('notes') + latitude = models.DecimalField('latitude', max_digits=11, decimal_places=8, blank=True) + longitude = models.DecimalField('longitude', max_digits=11, decimal_places=8, blank=True) + notes = models.TextField('notes', blank=True) class Equipment(models.Model): @@ -70,7 +70,7 @@ class Session(models.Model): related_name='sessions', null=True ) - notes = models.TextField('notes') + notes = models.TextField('notes', blank=True) class Round(models.Model): @@ -93,4 +93,4 @@ class Round(models.Model): on_delete=models.CASCADE, related_name='rounds' ) - notes = models.TextField('notes') + notes = models.TextField('notes', blank=True) diff --git a/gym/serializers.py b/gym/serializers.py new file mode 100644 index 0000000..fe4ab71 --- /dev/null +++ b/gym/serializers.py @@ -0,0 +1,22 @@ +from django.contrib.auth.models import User +from rest_framework import serializers + +from gym.models import Room, Equipment + + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ('id', 'username', 'email', 'first_name', 'last_name') + + +class RoomSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Room + fields = ('url', 'name', 'latitude', 'longitude', 'notes', 'equipments') + + +class EquipmentSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Equipment + fields = ('url', 'name', 'room') diff --git a/gym/urls.py b/gym/urls.py new file mode 100644 index 0000000..409e078 --- /dev/null +++ b/gym/urls.py @@ -0,0 +1,21 @@ +from django.conf.urls import url, include +from rest_framework import routers +from . import views + +router = routers.DefaultRouter() +router.register(r'rooms', views.RoomViewSet) +router.register(r'equipments', views.EquipmentViewSet) + +# Wire up our API using automatic URL routing. +# Additionally, we include login URLs for the browsable API. +urlpatterns = [ + url(r'^api/', include(router.urls)), + url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), + url(r'^api/me/', views.MeView.as_view()) +] + +from rest_framework.authtoken import views + +urlpatterns += [ + url(r'^api-token-auth/', views.obtain_auth_token) +] diff --git a/gym/views.py b/gym/views.py index 91ea44a..7499c0c 100644 --- a/gym/views.py +++ b/gym/views.py @@ -1,3 +1,24 @@ -from django.shortcuts import render +from django.contrib.auth.models import User +from rest_framework import viewsets +from rest_framework.generics import RetrieveUpdateAPIView -# Create your views here. +from gym.models import Room, Equipment +from gym.serializers import RoomSerializer, EquipmentSerializer, UserSerializer + + +class MeView(RetrieveUpdateAPIView): + serializer_class = UserSerializer + queryset = User.objects.none() + + def get_object(self): + return self.request.user + + +class RoomViewSet(viewsets.ModelViewSet): + queryset = Room.objects.all().order_by('name') + serializer_class = RoomSerializer + + +class EquipmentViewSet(viewsets.ModelViewSet): + queryset = Equipment.objects.all().order_by('name') + serializer_class = EquipmentSerializer \ No newline at end of file diff --git a/muscu/settings.py b/muscu/settings.py index 7ef77ea..4592fdd 100644 --- a/muscu/settings.py +++ b/muscu/settings.py @@ -15,7 +15,6 @@ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ @@ -27,7 +26,6 @@ DEBUG = True ALLOWED_HOSTS = [] - # Application definition INSTALLED_APPS = [ @@ -38,6 +36,8 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'gym', + 'rest_framework', + 'rest_framework.authtoken', ] MIDDLEWARE = [ @@ -70,7 +70,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'muscu.wsgi.application' - # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases @@ -81,7 +80,6 @@ DATABASES = { } } - # Password validation # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators @@ -100,13 +98,24 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissions' + ], + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.TokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', + ) +} # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'fr-fr' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Europe/Paris' USE_I18N = True @@ -114,7 +123,6 @@ USE_L10N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ diff --git a/muscu/urls.py b/muscu/urls.py index 3f70fe2..2e8a4f0 100644 --- a/muscu/urls.py +++ b/muscu/urls.py @@ -13,9 +13,11 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.conf.urls import url from django.contrib import admin -from django.urls import path +from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), + url(r'', include('gym.urls')), ]