Skip to content
Snippets Groups Projects
Commit ba6372bf authored by florimondmanca's avatar florimondmanca
Browse files

add Place model, API and tests

parent d57f67d3
Branches
No related tags found
No related merge requests found
......@@ -6,7 +6,8 @@ from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.db import transaction
from tests.factory import (ArticleFactory, CategoryFactory, KeyFigureFactory,
StudentFactory, TestimonyFactory, VisitFactory)
StudentFactory, TestimonyFactory, VisitFactory,
PlaceFactory)
from showcase_site.models import Category
......@@ -22,7 +23,7 @@ class Command(BaseCommand):
get_model,
(StudentFactory, CategoryFactory, ArticleFactory,
TestimonyFactory, KeyFigureFactory,
VisitFactory)
VisitFactory, PlaceFactory)
))
def add_arguments(self, parser):
......
......@@ -25,6 +25,7 @@ router = routers.SimpleRouter()
router.register('visits', visits_views.VisitViewSet)
router.register('visit-participants', visits_views.VisitParticipantsViewSet,
base_name='visit-participants')
router.register(r'places', visits_views.PlaceViewSet)
# Users views
router.register(r'users', users_views.UserViewSet)
......
......@@ -229,6 +229,16 @@ class KeyFigureFactory(factory.DjangoModelFactory):
order = factory.Sequence(lambda n: n)
class PlaceFactory(factory.DjangoModelFactory):
"""Place object factory."""
class Meta: # noqa
model = visits.models.Place
name = factory.Faker('company', locale='fr')
address = factory.Faker('address', locale='fr')
class VisitFactory(factory.DjangoModelFactory):
"""Visit object factory."""
......@@ -245,7 +255,15 @@ class VisitFactory(factory.DjangoModelFactory):
summary = factory.LazyAttribute(lambda o: ' '.join(o._summary))
_description = factory.Faker('paragraphs', nb=5, locale='fr')
description = factory.LazyAttribute(lambda o: '\n'.join(o._description))
place = factory.Faker('address', locale='fr')
@factory.lazy_attribute
def place(self):
places = visits.models.Place.objects.all()
# return an existing place in 30% of cases
if places and random.random() < .3:
return random.choice(places)
# otherwise create a new place
return PlaceFactory.create()
@factory.lazy_attribute
def date(self):
......
"""Place model tests."""
from visits.models import Place
from tests.factory import PlaceFactory
from tests.utils import ModelTestCase
class PlaceTest(ModelTestCase):
"""Test the Place model."""
model = Place
field_tests = {
'name': {
'verbose_name': 'nom',
'max_length': 200,
},
'address': {
'verbose_name': 'adresse',
'max_length': 200,
},
}
model_tests = {
'verbose_name': 'lieu',
'verbose_name_plural': 'lieux',
'ordering': ('name',),
}
@classmethod
def setUpTestData(cls):
cls.obj = PlaceFactory.create()
def test_get_absolute_url(self):
url = self.obj.get_absolute_url()
expected = '/api/places/{}/'.format(self.obj.pk)
self.assertEqual(url, expected)
response = self.client.get(url)
self.assertEqual(200, response.status_code)
def test_str_is_name(self):
self.assertEqual(str(self.obj), str(self.obj.name))
......@@ -28,7 +28,6 @@ class VisitTest(ModelTestCase):
},
'place': {
'verbose_name': 'lieu',
'max_length': 100,
},
'deadline': {
'verbose_name': "date limite d'inscription",
......
......@@ -2,7 +2,7 @@
from django import forms
from django.contrib import admin
from .models import Visit
from .models import Visit, Place
# Register your models here.
......@@ -78,3 +78,14 @@ class VisitAdmin(admin.ModelAdmin):
def num_participants(self, obj):
return obj.participants.count()
num_participants.short_description = 'Participants'
@admin.register(Place)
class PlaceAdmin(admin.ModelAdmin):
"""Admin panel for places."""
list_display = ('id', '__str__', 'address', 'num_visits')
def num_visits(self, obj):
return obj.visit_set.count()
num_visits.short_description = 'Sorties ici'
......@@ -103,13 +103,11 @@ class Visit(models.Model):
"la sortie. Ce champ supporte Markdown."
))
# TODO Place model
place = models.CharField(
'lieu', max_length=100,
help_text=(
"Indiquer simplement le nom du lieu où se déroule la "
"sortie. L'adresse exacte de rendez-vous devrait plutôt"
"être précisé dans la fiche sortie."
))
place = models.ForeignKey(
'Place',
verbose_name='lieu',
on_delete=models.SET_NULL,
null=True)
date = models.DateTimeField(
help_text="Heure de début de la sortie. Format de l'heure : hh:mm.")
deadline = models.DateTimeField(
......@@ -168,3 +166,21 @@ class Visit(models.Model):
def __str__(self):
return str(self.title)
class Place(models.Model):
"""Represents a place a visit happens at."""
name = models.CharField('nom', max_length=200)
address = models.CharField('adresse', max_length=200)
class Meta: # noqa
verbose_name = 'lieu'
verbose_name_plural = 'lieux'
ordering = ('name',)
def get_absolute_url(self):
return reverse('api:place-detail', args=[str(self.pk)])
def __str__(self):
return str(self.name)
......@@ -5,7 +5,14 @@ from rest_framework import serializers
from users.models import Student
from .models import Visit, VisitParticipant
from .models import Visit, VisitParticipant, Place
class PlaceSerializer(serializers.ModelSerializer):
class Meta: # noqa
model = Place
fields = ('id', 'name', 'address')
class VisitSerializer(serializers.HyperlinkedModelSerializer):
......@@ -13,6 +20,7 @@ class VisitSerializer(serializers.HyperlinkedModelSerializer):
participants = serializers.StringRelatedField(many=True)
passed = serializers.SerializerMethodField()
place = PlaceSerializer(read_only=True)
def get_passed(self, obj):
return obj.date < now()
......
......@@ -7,12 +7,12 @@ from rest_framework.response import Response
from rest_framework import mixins
from rest_framework.decorators import list_route
from dry_rest_permissions.generics import DRYPermissions
from .serializers import VisitSerializer
from .serializers import VisitSerializer, PlaceSerializer
from .serializers import VisitParticipantReadSerializer
from .serializers import VisitParticipantWriteSerializer
from .serializers import VisitParticipantIdentifySerializer
from .serializers import VisitParticipantDetailSerializer
from .models import Visit, VisitParticipant
from .models import Visit, VisitParticipant, Place
from users.models import Student
......@@ -77,3 +77,9 @@ class VisitParticipantsViewSet(mixins.CreateModelMixin,
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
class PlaceViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Place.objects.all()
serializer_class = PlaceSerializer
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment