diff --git a/Pipfile b/Pipfile
index 6f1b3be..da3e4c9 100644
--- a/Pipfile
+++ b/Pipfile
@@ -9,6 +9,7 @@ name = "pypi"
django = "*"
djangorestframework = "*"
+"django-bootstrap4" = "*"
[dev-packages]
diff --git a/Pipfile.lock b/Pipfile.lock
index 9c5b5e3..425954d 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "1f3d4cc7027911c0d5599450f18f080ccf209827c665920bad7fc6e832bb3b38"
+ "sha256": "c3ee9bacf90669123493994e4f194606cd953134dd819c73684629335c5a7ee6"
},
"host-environment-markers": {
"implementation_name": "cpython",
@@ -34,6 +34,12 @@
],
"version": "==2.0.2"
},
+ "django-bootstrap4": {
+ "hashes": [
+ "sha256:6db4a27b33851833e68b96344f9df063150dcace8d4787ebfc21eceb55196945"
+ ],
+ "version": "==0.0.6"
+ },
"djangorestframework": {
"hashes": [
"sha256:1f6baf40ed456ed2af6bd1a4ff8bbc3503cebea16509993aea2b7085bc097766",
diff --git a/gym/admin.py b/gym/admin.py
index 8c38f3f..5d256f9 100644
--- a/gym/admin.py
+++ b/gym/admin.py
@@ -1,3 +1,28 @@
from django.contrib import admin
-# Register your models here.
+from gym.models import Room, Equipment, Setting, TheoreticalMax, Session, Round
+
+
+@admin.register(Room)
+class RoomAdmin(admin.ModelAdmin):
+ pass
+
+
+@admin.register(Equipment)
+class EquipmentAdmin(admin.ModelAdmin):
+ pass
+
+
+@admin.register(TheoreticalMax)
+class TheoreticalMaxAdmin(admin.ModelAdmin):
+ pass
+
+
+@admin.register(Session)
+class SessionAdmin(admin.ModelAdmin):
+ pass
+
+
+@admin.register(Round)
+class RoundAdmin(admin.ModelAdmin):
+ pass
diff --git a/gym/migrations/0003_auto_20180303_1801.py b/gym/migrations/0003_auto_20180303_1801.py
new file mode 100644
index 0000000..f11a14d
--- /dev/null
+++ b/gym/migrations/0003_auto_20180303_1801.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.2 on 2018-03-03 17:01
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gym', '0002_auto_20180303_1201'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='session',
+ name='date',
+ field=models.DateTimeField(verbose_name='date et heure de début'),
+ ),
+ ]
diff --git a/gym/migrations/0004_auto_20180303_1801.py b/gym/migrations/0004_auto_20180303_1801.py
new file mode 100644
index 0000000..9799ee8
--- /dev/null
+++ b/gym/migrations/0004_auto_20180303_1801.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.2 on 2018-03-03 17:01
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gym', '0003_auto_20180303_1801'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='session',
+ old_name='date',
+ new_name='start',
+ ),
+ ]
diff --git a/gym/models.py b/gym/models.py
index 991980b..b1c329f 100644
--- a/gym/models.py
+++ b/gym/models.py
@@ -11,6 +11,9 @@ class Room(models.Model):
longitude = models.DecimalField('longitude', max_digits=11, decimal_places=8, blank=True)
notes = models.TextField('notes', blank=True)
+ def __str__(self):
+ return self.name
+
class Equipment(models.Model):
class Meta:
@@ -26,6 +29,13 @@ class Equipment(models.Model):
null=True
)
+ @property
+ def last_theoretical_max(self):
+ return self.theoretical_maxs.order_by('-start').first()
+
+ def __str__(self):
+ return f'{self.name} ({self.room.name})'
+
class Setting(models.Model):
class Meta:
@@ -41,6 +51,9 @@ class Setting(models.Model):
name = models.CharField('nom', max_length=200)
value = models.CharField('valeur', max_length=200)
+ def __str__(self):
+ return f'{self.name}={self.value}'
+
class TheoreticalMax(models.Model):
class Meta:
@@ -56,13 +69,16 @@ class TheoreticalMax(models.Model):
date = models.DateField('date')
value = models.FloatField('valeur')
+ def __str__(self):
+ return f'{self.value}kg le {self.date}'
+
class Session(models.Model):
class Meta:
verbose_name = 'séance'
verbose_name_plural = 'séances'
- date = models.DateField('date')
+ start = models.DateTimeField('date et heure de début')
room = models.ForeignKey(
verbose_name='salle',
to=Room,
diff --git a/gym/serializers.py b/gym/serializers.py
deleted file mode 100644
index fe4ab71..0000000
--- a/gym/serializers.py
+++ /dev/null
@@ -1,22 +0,0 @@
-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/templates/gym/base.html b/gym/templates/gym/base.html
new file mode 100644
index 0000000..db8a458
--- /dev/null
+++ b/gym/templates/gym/base.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ {% block add-head %}
+ {% endblock %}
+
+ Gym · {% block title %}Home{% endblock %}
+
+
+
+ {% for message in messages %}
+
+ {{ message }}
+
+
+ {% endfor %}
+ {% block content %}
+ {% endblock %}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gym/templates/gym/equipment.html b/gym/templates/gym/equipment.html
new file mode 100644
index 0000000..f6a93cf
--- /dev/null
+++ b/gym/templates/gym/equipment.html
@@ -0,0 +1,26 @@
+{% extends 'gym/base.html' %}
+
+{% block content %}
+
+
+
{% block title %}{{ equipment.name }} ({{ equipment.room.name }}){% endblock %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/equipment_edit.html b/gym/templates/gym/equipment_edit.html
new file mode 100644
index 0000000..1225189
--- /dev/null
+++ b/gym/templates/gym/equipment_edit.html
@@ -0,0 +1,22 @@
+{% extends 'gym/base.html' %}
+{% load bootstrap4 %}
+
+{% block content %}
+
+
+
{% block title %}Ajouter une machine{% endblock %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/room.html b/gym/templates/gym/room.html
new file mode 100644
index 0000000..0595a7d
--- /dev/null
+++ b/gym/templates/gym/room.html
@@ -0,0 +1,38 @@
+{% extends 'gym/base.html' %}
+
+{% block content %}
+
+
+
{% block title %}{{ room.name }}{% endblock %}
+
+
+
+
+ {% if room.sessions.all %}
+
+ {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/rooms.html b/gym/templates/gym/rooms.html
new file mode 100644
index 0000000..a49fee0
--- /dev/null
+++ b/gym/templates/gym/rooms.html
@@ -0,0 +1,18 @@
+{% extends 'gym/base.html' %}
+
+{% block content %}
+
+
+
{% block title %}Salles{% endblock %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/session_detail.html b/gym/templates/gym/session_detail.html
new file mode 100644
index 0000000..4ddf0e5
--- /dev/null
+++ b/gym/templates/gym/session_detail.html
@@ -0,0 +1,42 @@
+{% extends 'gym/base.html' %}
+{% load bootstrap4 %}
+
+{% block content %}
+
+
+
{% block title %}Séance en cours{% endblock %}
+
+
+
+
+
+
+
+ - {{ session.room.name }}
+ - {{ session.start }}
+ {% if session.notes %}
+ - {{ session.notes }}
+ {% endif %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/session_edit.html b/gym/templates/gym/session_edit.html
new file mode 100644
index 0000000..53dbecc
--- /dev/null
+++ b/gym/templates/gym/session_edit.html
@@ -0,0 +1,29 @@
+{% extends 'gym/base.html' %}
+{% load bootstrap4 %}
+
+{% block content %}
+
+
+
{% block title %}{{ title }} une séance{% endblock %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/setting_confirm_delete.html b/gym/templates/gym/setting_confirm_delete.html
new file mode 100644
index 0000000..9036ab1
--- /dev/null
+++ b/gym/templates/gym/setting_confirm_delete.html
@@ -0,0 +1,19 @@
+{% extends 'gym/base.html' %}
+{% load bootstrap4 %}
+
+{% block content %}
+
+
+
{% block title %}Supprimer un réglage{% endblock %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/templates/gym/setting_edit.html b/gym/templates/gym/setting_edit.html
new file mode 100644
index 0000000..cf80636
--- /dev/null
+++ b/gym/templates/gym/setting_edit.html
@@ -0,0 +1,31 @@
+{% extends 'gym/base.html' %}
+{% load bootstrap4 %}
+
+{% block content %}
+
+
+
{% block title %}{{ title }} un réglage{% endblock %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/gym/urls.py b/gym/urls.py
index 409e078..11ce67d 100644
--- a/gym/urls.py
+++ b/gym/urls.py
@@ -1,21 +1,19 @@
-from django.conf.urls import url, include
-from rest_framework import routers
-from . import views
+from django.urls import path
-router = routers.DefaultRouter()
-router.register(r'rooms', views.RoomViewSet)
-router.register(r'equipments', views.EquipmentViewSet)
+from . import views
# 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())
+ path('', views.RoomListView.as_view(), name='rooms-list'),
+ path('rooms//', views.RoomDetailView.as_view(), name='room-detail'),
+ path('equipment/add/', views.EquipmentCreateView.as_view(), name='equipment-create'),
+ path('equipment//', views.EquipmentDetailView.as_view(), name='equipment-detail'),
+ path('setting/add/', views.SettingCreateView.as_view(), name='setting-create'),
+ path('setting//', views.SettingUpdateView.as_view(), name='setting-edit'),
+ path('setting//delete', views.SettingDeleteView.as_view(), name='setting-delete'),
+ path('session/start/', views.SessionCreateView.as_view(), name='session-start'),
+ path('session//', views.SessionDetailView.as_view(), name='session-detail'),
+ # path('session//delete', views.SessionDeleteView.as_view(), name='session-delete'),
]
-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 7499c0c..9ebcdfd 100644
--- a/gym/views.py
+++ b/gym/views.py
@@ -1,24 +1,135 @@
-from django.contrib.auth.models import User
-from rest_framework import viewsets
-from rest_framework.generics import RetrieveUpdateAPIView
+import datetime
-from gym.models import Room, Equipment
-from gym.serializers import RoomSerializer, EquipmentSerializer, UserSerializer
+from django.shortcuts import get_object_or_404
+from django.urls import reverse
+from django.views import generic
+
+from gym.models import Room, Equipment, Setting, Session
-class MeView(RetrieveUpdateAPIView):
- serializer_class = UserSerializer
- queryset = User.objects.none()
-
- def get_object(self):
- return self.request.user
-
-
-class RoomViewSet(viewsets.ModelViewSet):
+class RoomListView(generic.ListView):
queryset = Room.objects.all().order_by('name')
- serializer_class = RoomSerializer
+ context_object_name = 'rooms'
+ template_name = 'gym/rooms.html'
-class EquipmentViewSet(viewsets.ModelViewSet):
- queryset = Equipment.objects.all().order_by('name')
- serializer_class = EquipmentSerializer
\ No newline at end of file
+class RoomDetailView(generic.DetailView):
+ model = Room
+ context_object_name = 'room'
+ template_name = 'gym/room.html'
+
+
+class EquipmentDetailView(generic.DetailView):
+ model = Equipment
+ context_object_name = 'equipment'
+ template_name = 'gym/equipment.html'
+
+
+class EquipmentCreateView(generic.CreateView):
+ model = Equipment
+ fields = ['room', 'name']
+ template_name = 'gym/equipment_edit.html'
+ room = None
+
+ def get_success_url(self):
+ return reverse('equipment-detail', kwargs={'pk': self.object.pk})
+
+ def dispatch(self, request, *args, **kwargs):
+ default_room_id = self.request.GET.get('room')
+ if default_room_id:
+ self.room = get_object_or_404(Room, pk=default_room_id)
+
+ return super().dispatch(request, *args, **kwargs)
+
+ def get_initial(self):
+ initial = super().get_initial()
+ initial['room'] = self.room
+
+ return initial
+
+
+class SettingCreateView(generic.CreateView):
+ model = Setting
+ fields = ['equipment', 'name', 'value']
+ template_name = 'gym/setting_edit.html'
+ equipment = None
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = 'Ajouter'
+ context['equipment'] = self.equipment
+ return context
+
+ def dispatch(self, request, *args, **kwargs):
+ default_equipment_id = self.request.GET.get('equipment')
+ if default_equipment_id:
+ self.equipment = get_object_or_404(Equipment, pk=default_equipment_id)
+
+ return super().dispatch(request, *args, **kwargs)
+
+ def get_initial(self):
+ initial = super().get_initial()
+ initial['equipment'] = self.equipment
+
+ return initial
+
+ def get_success_url(self):
+ return reverse('equipment-detail', kwargs={'pk': self.object.equipment.pk})
+
+
+class SettingUpdateView(generic.UpdateView):
+ model = Setting
+ fields = ['equipment', 'name', 'value']
+ template_name = 'gym/setting_edit.html'
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['edit'] = True
+ context['title'] = 'Modifier'
+ context['equipment'] = self.object.equipment
+ return context
+
+ def get_success_url(self):
+ return reverse('equipment-detail', kwargs={'pk': self.object.equipment.pk})
+
+
+class SettingDeleteView(generic.DeleteView):
+ model = Setting
+ template_name = 'gym/setting_confirm_delete.html'
+ context_object_name = 'setting'
+
+ def get_success_url(self):
+ return reverse('equipment-detail', kwargs={'pk': self.object.equipment.pk})
+
+
+class SessionCreateView(generic.CreateView):
+ model = Session
+ fields = ['room', 'start']
+ template_name = 'gym/session_edit.html'
+ room = None
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = 'Démarrer'
+ context['room'] = self.room
+ return context
+
+ def get_success_url(self):
+ return reverse('session-detail', kwargs={'pk': self.object.pk})
+
+ def dispatch(self, request, *args, **kwargs):
+ self.room = get_object_or_404(Room, pk=self.request.GET.get('room'))
+ return super().dispatch(request, *args, **kwargs)
+
+ def get_initial(self):
+ initial = super().get_initial()
+ initial['room'] = self.room
+ initial['start'] = datetime.datetime.now()
+
+ return initial
+
+
+class SessionDetailView(generic.DetailView):
+ model = Session
+ context_object_name = 'session'
+ template_name = 'gym/session_detail.html'
diff --git a/muscu/settings.py b/muscu/settings.py
index 4592fdd..1f27932 100644
--- a/muscu/settings.py
+++ b/muscu/settings.py
@@ -24,7 +24,7 @@ SECRET_KEY = 'x*8q7sd14&a%cu95$h@jl&bb&j(j*-6h5!3atz*v%!zo3hd4'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = ['*']
# Application definition
@@ -36,8 +36,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'gym',
- 'rest_framework',
- 'rest_framework.authtoken',
+ 'bootstrap4',
]
MIDDLEWARE = [
@@ -98,18 +97,6 @@ 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/