Skip to content

Commit

Permalink
Ready for deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
tylercote committed Nov 25, 2019
1 parent 0a7539e commit 6345fa9
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 136 deletions.
280 changes: 151 additions & 129 deletions .idea/workspace.xml

Large diffs are not rendered by default.

Binary file modified mymusix/mymusix/__pycache__/api_views.cpython-38.pyc
Binary file not shown.
Binary file modified mymusix/mymusix/__pycache__/models.cpython-38.pyc
Binary file not shown.
Binary file modified mymusix/mymusix/__pycache__/serializers.cpython-38.pyc
Binary file not shown.
Binary file modified mymusix/mymusix/__pycache__/settings.cpython-38.pyc
Binary file not shown.
Binary file modified mymusix/mymusix/__pycache__/urls.cpython-38.pyc
Binary file not shown.
19 changes: 17 additions & 2 deletions mymusix/mymusix/api_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .models import Review
from django.db.models.base import ObjectDoesNotExist, MultipleObjectsReturned
from django.db import connection
from .permissions import IsOwnerOrReadOnly


@api_view(['GET'])
Expand Down Expand Up @@ -57,31 +58,41 @@ def dictfetchall(cursor):
class GenreViewset(viewsets.ModelViewSet):
queryset = models.Genre.objects.all()
serializer_class = serializers.GenreSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]


class ArtistViewset(viewsets.ModelViewSet):
queryset = models.Artist.objects.all()
serializer_class = serializers.ArtistSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]


class VenueViewset(viewsets.ModelViewSet):
queryset = models.Venue.objects.all()
serializer_class = serializers.VenueSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]


class FestivalViewset(viewsets.ModelViewSet):
queryset = models.Festival.objects.all()
serializer_class = serializers.FestivalSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

@action(detail=True)
def get_artists(self, request, pk):
festival = self.get_object()
data = list(festival.artists.values())
return JsonResponse(data, safe=False)


class ConcertViewset(viewsets.ModelViewSet):
queryset = models.Concert.objects.all()
serializer_class = serializers.ConcertSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]

def get_queryset(self):
queryset = models.Concert.objects.all().filter(user=self.request.user)
return queryset

@action(detail=False)
def get_concerts(self, request):
Expand All @@ -91,7 +102,8 @@ def get_concerts(self, request):
"JOIN artists AS a ON c.artist_id = a.id "
"JOIN venues AS v ON c.venue_id = v.id "
"LEFT JOIN festivals AS f ON c.festival_id = f.id "
"LEFT JOIN reviews as r ON c.id = r.concert_id;")
"LEFT JOIN reviews as r ON c.id = r.concert_id "
"WHERE c.user_id = " + str(request.user.id) + ";")
# rows = cursor.fetchall()
rowDict = dictfetchall(cursor)
return JsonResponse(rowDict, safe=False)
Expand All @@ -101,6 +113,7 @@ def add_concert(self, request):
serializer = NewConcertSerializer(data=request.data)
serializer.is_valid()
concert = Concert()
concert.user = request.user
concert.date = serializer.data["date"]
try:
artist = Artist.objects.get(name=serializer.data["artist"])
Expand All @@ -126,6 +139,7 @@ def add_concert(self, request):
concert.save()

newReview = Review()
newReview.user = request.user
newReview.concert_id = concert.pk
newReview.stars = serializer.data["rating"]
newReview.comments = serializer.data["comments"]
Expand All @@ -136,4 +150,5 @@ def add_concert(self, request):

class ReviewViewset(viewsets.ModelViewSet):
queryset = models.Review.objects.all()
serializer_class = serializers.ReviewSerializer
serializer_class = serializers.ReviewSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
38 changes: 38 additions & 0 deletions mymusix/mymusix/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q


class EmailOrUsernameModelBackend(ModelBackend):
"""
Authentication backend which allows users to authenticate using either their
username or email address
Source: https://stackoverflow.com/a/35836674/59984
"""

def authenticate(self, request, username=None, password=None, **kwargs):
# n.b. Django <2.1 does not pass the `request`

user_model = get_user_model()

if username is None:
username = kwargs.get(user_model.USERNAME_FIELD)

# The `username` field is allows to contain `@` characters so
# technically a given email address could be present in either field,
# possibly even for different users, so we'll query for all matching
# records and test each one.
users = user_model._default_manager.filter(
Q(**{user_model.USERNAME_FIELD: username}) | Q(email__iexact=username)
)

# Test whether any matched user has the provided password:
for user in users:
if user.check_password(password):
return user
if not users:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (see
# https://code.djangoproject.com/ticket/20760)
user_model().set_password(password)
6 changes: 5 additions & 1 deletion mymusix/mymusix/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.db import models

from django.conf import settings

class Genre(models.Model):
id = models.AutoField(primary_key=True)
Expand Down Expand Up @@ -41,6 +41,8 @@ class Meta:

class Concert(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
null=True, blank=True, on_delete=models.SET_NULL)
artist = models.ForeignKey(Artist, on_delete=models.PROTECT)
venue = models.ForeignKey(Venue, on_delete=models.PROTECT)
festival = models.ForeignKey(Festival, blank=True, null=True, on_delete=models.SET_NULL)
Expand All @@ -52,6 +54,8 @@ class Meta:

class Review(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
null=True, blank=True, on_delete=models.SET_NULL)
concert = models.ForeignKey(Concert, on_delete=models.CASCADE)
stars = models.DecimalField(decimal_places=2, max_digits=3, null=True, blank=True)
comments = models.CharField(max_length=300, null=True, blank=True)
Expand Down
16 changes: 16 additions & 0 deletions mymusix/mymusix/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""

def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True

# Write permissions are only allowed to the owner of the snippet.
return obj.user_id == request.user.id
7 changes: 4 additions & 3 deletions mymusix/mymusix/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class UserSerializer(serializers.ModelSerializer):

class Meta:
model = User
fields = ('username',)
fields = ('id', 'username')


class UserSerializerWithToken(serializers.ModelSerializer):
Expand Down Expand Up @@ -64,10 +64,11 @@ class Meta:
class ConcertSerializer(serializers.ModelSerializer):
class Meta:
model = models.Concert
fields = ('id', 'artist', 'venue', 'festival', 'date')
fields = ('id', 'user', 'artist', 'venue', 'festival', 'date')


class NewConcertSerializer(serializers.Serializer):
user = serializers.IntegerField()
artist = serializers.CharField()
rating = serializers.DecimalField(decimal_places=2, max_digits=3)
comments = serializers.CharField()
Expand All @@ -79,4 +80,4 @@ class NewConcertSerializer(serializers.Serializer):
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = models.Review
fields = ('id', 'concert', 'stars', 'comments')
fields = ('id', 'user', 'concert', 'stars', 'comments')
2 changes: 2 additions & 0 deletions mymusix/mymusix/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
),
}

AUTHENTICATION_BACKENDS = ['mymusix.backends.EmailOrUsernameModelBackend']

CORS_ORIGIN_ALLOW_ALL = True

CORS_ORIGIN_WHITELIST = (
Expand Down
Binary file modified mymusix/scripts/__pycache__/add_festival_artists.cpython-38.pyc
Binary file not shown.
2 changes: 1 addition & 1 deletion mymusix/scripts/add_festival_artists.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


def run():
with open(os.path.join(__location__, 'osheaga2018'), 'r') as f:
with open(os.path.join(__location__, 'firefly2019'), 'r') as f:

i = 0
newFestival = Festival()
Expand Down

0 comments on commit 6345fa9

Please sign in to comment.