Skip to content

Commit 07cd8a4

Browse files
authored
Merge pull request #23 from CodeForPhilly/third-places-12
Add initial user endpoints
2 parents 66dd1ad + 16c908f commit 07cd8a4

9 files changed

Lines changed: 106 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to release number versioning.
1313
- Added Docker containers with docker-compose [#10](https://github.com/CodeForPhilly/third-places/pull/10)
1414
- Set up Leaflet React component and boiletplate homepage[#7](https://github.com/CodeForPhilly/third-places/issues/7)
1515
- Added initial Django models & migration [#21](https://github.com/CodeForPhilly/third-places/pull/21)
16+
- Added initial REST endpoints for Users [#23](https://github.com/CodeForPhilly/third-places/pull/23)
1617
- Added buttons at bottom of Map [#40](https://github.com/CodeForPhilly/third-places/pull/40)
1718

1819
### Changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,6 @@ Access the following ports from localhost to access their respective services
6767

6868
### Api Reference
6969

70-
`/api/`: Hello world!
70+
- `/api/`: Hello world!
71+
- `/users/`: `GET`, `POST` users
72+
- `/users/{id}`: `GET`, `PUT` specific user details

src/django/api/admin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
from django.contrib import admin
2+
from .models import ThirdPlaceUser
23

3-
# Register your models here.
4+
admin.site.register(ThirdPlaceUser)

src/django/api/migrations/0001_initial.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 4.2 on 2023-05-03 04:05
1+
# Generated by Django 4.2 on 2023-05-05 01:40
22

33
import django.contrib.gis.db.models.fields
44
from django.db import migrations, models
@@ -31,8 +31,8 @@ class Migration(migrations.Migration):
3131
('name', models.TextField()),
3232
('address', models.TextField()),
3333
('price_category', models.CharField(max_length=5)),
34-
('created_datetime', models.DateTimeField()),
35-
('modified_datetime', models.DateTimeField()),
34+
('created_datetime', models.DateTimeField(auto_now_add=True)),
35+
('modified_datetime', models.DateTimeField(auto_now=True)),
3636
('hours', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.businesshours')),
3737
],
3838
),
@@ -60,9 +60,10 @@ class Migration(migrations.Migration):
6060
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
6161
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
6262
('email', models.EmailField(max_length=254, unique=True)),
63+
('username', models.CharField(max_length=150, unique=True)),
6364
('display_name', models.TextField()),
64-
('created_datetime', models.DateTimeField()),
65-
('modified_datetime', models.DateTimeField()),
65+
('created_datetime', models.DateTimeField(auto_now_add=True)),
66+
('modified_datetime', models.DateTimeField(auto_now=True)),
6667
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='thirdplaceuser_groups', related_query_name='thirdplaceuser', to='auth.group', verbose_name='groups')),
6768
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='thirdplaceuser_user_permissions', related_query_name='thirdplaceuser', to='auth.permission', verbose_name='user permissions')),
6869
],
@@ -76,8 +77,8 @@ class Migration(migrations.Migration):
7677
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
7778
('name', models.TextField()),
7879
('value', models.DecimalField(decimal_places=1, max_digits=2)),
79-
('created_datetime', models.DateTimeField()),
80-
('modified_datetime', models.DateTimeField()),
80+
('created_datetime', models.DateTimeField(auto_now_add=True)),
81+
('modified_datetime', models.DateTimeField(auto_now=True)),
8182
('locations', models.ManyToManyField(related_name='tags', to='api.location')),
8283
('tag_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.tagtype')),
8384
],

src/django/api/models.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class Location(models.Model):
5353
hours = models.ForeignKey(BusinessHours, on_delete=models.CASCADE)
5454
location_type = models.ForeignKey(LocationType, on_delete=models.CASCADE)
5555
price_category = models.CharField(max_length=5)
56-
created_datetime = models.DateTimeField()
57-
modified_datetime = models.DateTimeField()
56+
created_datetime = models.DateTimeField(auto_now_add=True)
57+
modified_datetime = models.DateTimeField(auto_now=True)
5858

5959
REQUIRED_FIELDS = ["location", "location_type", "created_datetime", "modified_datetime"]
6060

@@ -67,8 +67,8 @@ class Tag(models.Model):
6767
locations = models.ManyToManyField(Location, related_name='tags')
6868
tag_type = models.ForeignKey(TagType, on_delete=models.CASCADE)
6969
value = models.DecimalField(decimal_places=1, max_digits=2)
70-
created_datetime = models.DateTimeField()
71-
modified_datetime = models.DateTimeField()
70+
created_datetime = models.DateTimeField(auto_now_add=True)
71+
modified_datetime = models.DateTimeField(auto_now=True)
7272

7373
REQUIRED_FIELDS = ["name", "tag_type", "value", "created_datetime", "modified_datetime"]
7474

@@ -78,9 +78,10 @@ def __str__(self):
7878

7979
class ThirdPlaceUser(AbstractBaseUser, PermissionsMixin):
8080
email = models.EmailField(unique=True)
81+
username = models.CharField(max_length=150, unique=True)
8182
display_name = models.TextField()
82-
created_datetime = models.DateTimeField()
83-
modified_datetime = models.DateTimeField()
83+
created_datetime = models.DateTimeField(auto_now_add=True)
84+
modified_datetime = models.DateTimeField(auto_now=True)
8485

8586
groups = models.ManyToManyField(
8687
Group,

src/django/api/serializers.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import datetime
2+
3+
from rest_framework import serializers
4+
from .models import ThirdPlaceUser
5+
6+
7+
class ThirdPlaceUserSerializer(serializers.ModelSerializer):
8+
password = serializers.CharField(write_only=True)
9+
display_name = serializers.CharField(required=False)
10+
created_datetime = serializers.DateTimeField(read_only=True, initial=datetime.datetime)
11+
modified_datetime = serializers.DateTimeField(read_only=True, initial=datetime.datetime)
12+
13+
class Meta:
14+
model = ThirdPlaceUser
15+
fields = (
16+
"username",
17+
"email",
18+
"password",
19+
"display_name",
20+
"created_datetime",
21+
"modified_datetime"
22+
)
23+
24+
25+
26+
class ThirdPlaceUserPutSerializer(serializers.ModelSerializer):
27+
username = serializers.CharField(required=False)
28+
email = serializers.EmailField(required=False)
29+
password = serializers.CharField(write_only=True, required=False)
30+
display_name = serializers.CharField(required=False)
31+
32+
class Meta:
33+
model = ThirdPlaceUser
34+
fields = (
35+
"username",
36+
"email",
37+
"password",
38+
"display_name",
39+
)

src/django/api/urls.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
from django.urls import path
2-
2+
from rest_framework.urlpatterns import format_suffix_patterns
33
from . import views
44

55
urlpatterns = [
66
path("", views.index, name="index"),
7+
path("users/", views.third_place_user_list),
8+
path("users/<int:pk>", views.third_place_user_detail)
79
]
10+
11+
urlpatterns = format_suffix_patterns(urlpatterns)

src/django/api/views.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
11
from django.http import HttpResponse
2+
from rest_framework import status
3+
from rest_framework.decorators import api_view
4+
from rest_framework.response import Response
5+
from .serializers import ThirdPlaceUserSerializer, ThirdPlaceUserPutSerializer
6+
from .models import ThirdPlaceUser
27

38

49
def index(request):
510
return HttpResponse("Hello, world!")
11+
12+
13+
@api_view(['GET', 'POST'])
14+
def third_place_user_list(request):
15+
if request.method == 'GET':
16+
users = ThirdPlaceUser.objects.all()
17+
serializer = ThirdPlaceUserSerializer(users, many=True)
18+
return Response(serializer.data)
19+
20+
elif request.method == 'POST':
21+
serializer = ThirdPlaceUserSerializer(data=request.data)
22+
if serializer.is_valid():
23+
serializer.save()
24+
return Response(serializer.data, status=status.HTTP_201_CREATED)
25+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
26+
27+
28+
@api_view(['GET', 'PUT'])
29+
def third_place_user_detail(request, pk):
30+
try:
31+
user = ThirdPlaceUser.objects.get(pk=pk)
32+
except ThirdPlaceUser.DoesNotExist:
33+
return Response(status=status.HTTP_404_NOT_FOUND)
34+
35+
if request.method == 'GET':
36+
serializer = ThirdPlaceUserSerializer(user)
37+
return Response(serializer.data)
38+
39+
elif request.method == 'PUT':
40+
serializer = ThirdPlaceUserPutSerializer(user, data=request.data)
41+
if serializer.is_valid():
42+
serializer.save()
43+
return Response(serializer.data)
44+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
45+

src/django/thirdplaces/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"django.contrib.sessions",
3939
"django.contrib.messages",
4040
"django.contrib.staticfiles",
41+
"rest_framework",
4142
"api"
4243
]
4344

0 commit comments

Comments
 (0)