Created
March 3, 2020 19:25
-
-
Save pmburu/a0d31b5d9aa49fbc5eaecaa262c45478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib.auth.base_user import BaseUserManager | |
class UserManager(BaseUserManager): | |
use_in_migrations = True | |
def _create_user(self, email, name, country, password, **extra_fields): | |
""" | |
Creates and saves a User with the given email and password. | |
""" | |
if not email: | |
raise ValueError('The given email must be set') | |
email = self.normalize_email(email) | |
user = self.model( | |
email=email, | |
name=name, | |
country=country, | |
**extra_fields | |
) | |
user.set_password(password) | |
user.save(using=self._db) | |
return user | |
def create_user(self, email, name, country, password=None, **extra_fields): | |
extra_fields.setdefault('is_superuser', False) | |
return self._create_user(email, name, country, password, **extra_fields) | |
def create_superuser(self, email, name, country, password, **extra_fields): | |
extra_fields.setdefault('is_superuser', True) | |
if extra_fields.get('is_superuser') is not True: | |
raise ValueError('Superuser must have is_superuser=True.') | |
return self._create_user(email, name, country, password, **extra_fields) | |
raise ValueError('Please update your profession. Thank you') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
import uuid | |
from django.db import models | |
from django.db.models import Q | |
from django.contrib.auth.models import Group | |
from django.core.mail import send_mail | |
from django.contrib.auth.models import PermissionsMixin | |
from django.contrib.auth.base_user import AbstractBaseUser | |
from django.utils.translation import ugettext_lazy as _ | |
from django.db.models.signals import post_save | |
from django.dispatch import receiver | |
from allauth.account.signals import email_confirmed | |
# Third party imports and custom made libraries | |
from .managers import UserManager | |
from django_countries.fields import CountryField | |
from multiselectfield import MultiSelectField | |
# Creating The custom user model with the following attributes | |
''' | |
1. Full Name | |
2. Country of Residence | |
3. Email Address | |
4. Password | |
''' | |
class User(AbstractBaseUser, PermissionsMixin): | |
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
name = models.CharField(_('full name'), max_length=30, blank=True) | |
email = models.EmailField(_('email address'), unique=True) | |
country = CountryField() | |
# groups = models.ForeignKey(Group, on_delete=models.CASCADE) | |
date_joined = models.DateTimeField(_('date joined'), auto_now_add=True) | |
is_active = models.BooleanField(_('active'), default=True) | |
objects = UserManager() | |
USERNAME_FIELD = 'email' | |
REQUIRED_FIELDS = ['name', 'country'] | |
class Meta: | |
verbose_name = _('user') | |
verbose_name_plural = _('users') | |
db_table = 'auth_user' | |
def __str__(self): | |
return self.name | |
# def get_full_name(self): | |
# ''' | |
# Returns the first_name plus the last_name, with a space in between. | |
# ''' | |
# full_name = '%s %s' % (self.first_name, self.last_name) | |
# return full_name.strip() | |
def get_short_name(self): | |
''' | |
Returns the short name for the user. | |
''' | |
return self.name | |
def email_user(self, subject, message, from_email=None, **kwargs): | |
''' | |
Sends an email to this User. | |
''' | |
send_mail(subject, message, from_email, [self.email], **kwargs) | |
PROFESSION_CHOICES = ( | |
('MUSIC_PRODUCER', 'Music Producer'), | |
('RECORD_LABEL', 'Record Label'), | |
('SONGWRITER', 'Songwriter'), | |
('BOOKING_AGENT', 'Booking Agent'), | |
('SINGER', 'Singer'), | |
('RAPPER', 'Rapper'), | |
('SINGER_&_RAPPER', 'Singer and Rapper'), | |
('A_&_R_COORDINATOR', 'A&R Coordinator'), | |
('PERSONAL_MANAGER', 'Personal Manager'), | |
('CONCERT_PROMOTER', 'Concert Promoter'), | |
('TOUR_MANAGER', 'Tour Manager'), | |
('TOUR_COORDINATOR', 'Tour Coordinator'), | |
('RECORD_PRODUCER', 'Record Producer'), | |
('LYRICIST', 'Lyricist'), | |
('COMPOSER', 'Composer'), | |
('BACKGROUND_SINGER', 'Background Singer'), | |
('JAZZ_MUSICIAN', 'Jazz Musician'), | |
('MUSIC_PUBLISHER', 'Music Publisher'), | |
('SESSION_MUSICIAN', 'Session Musician'), | |
('OTHER', 'Other') | |
) | |
GENRE_CHOICES = ( | |
('AFRO_BEAT/AFRO_POP', 'Afro-Beat/Afro-Pop'), | |
('HIP_HOP/RAP', 'Hip-Hop/Rap'), | |
('POP_MUSIC', 'Pop Music'), | |
('ROCK_MUSIC', 'Rock Music'), | |
('ELECTRONIC', 'Electronic'), | |
('CLASSICAL', 'Classical'), | |
('ALTERNATIVE', 'Alternative'), | |
('R_&_B/SOUL', 'R&B/Soul'), | |
('COUNTRY_MUSIC', 'Country Music'), | |
('REGGAE', 'Reggae'), | |
('JAZZ', 'Jazz'), | |
('INDIE_POP', 'Indie Pop'), | |
('ACAPELLA', 'Acapella'), | |
('GOSPEL', 'Gospel'), | |
('BLUES', 'Blues') | |
) | |
class ProfileManager(models.Manager): | |
def is_artist(self, user_profession): | |
""" Is the user profile an artist? """ | |
user_profession = Profile.objects.filter( | |
Q(profession__contains='SINGER') | | |
Q(profession__contains='RAPPER') | | |
Q(profession__contains='SINGER_&_RAPPER') | | |
Q(profession__contains='JAZZ_MUSICIAN') | | |
Q(profession__contains='BACKGROUND_SINGER') | |
) | |
# user = user_profession.user | |
if user_profession: | |
return user_profession | |
else: | |
raise ValueError('Please update your profession. Thank you') | |
class Profile(models.Model): | |
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | |
user = models.OneToOneField( | |
User, on_delete=models.CASCADE, related_name="profile", blank=True, null=True) | |
profession = MultiSelectField(choices=PROFESSION_CHOICES, max_choices=2) | |
genre = MultiSelectField(choices=GENRE_CHOICES, max_choices=3) | |
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) | |
connect = models.ManyToManyField(to=User, related_name='connected_by') | |
objects = ProfileManager() | |
def __str__(self): | |
return self.user.name | |
@receiver(post_save, sender=User) | |
def create_user_profile(sender, instance, created, **kwargs): | |
if created: | |
Profile.objects.create(user=instance) | |
@receiver(post_save, sender=User) | |
def save_user_profile(sender, instance, **kwargs): | |
instance.profile.save() | |
@receiver(email_confirmed) | |
def email_confirmed_(request, email_address, **kwargs): | |
user = User.objects.get(email=email_address.email) | |
user.is_active = True | |
user.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# wm_accounts/utils.py | |
from django.core.exceptions import ObjectDoesNotExist | |
from common.exceptions import NotFound | |
from .models import User, Profile | |
import uuid | |
def get_user_object(**kwargs): | |
try: | |
return User.objects.get(**kwargs) | |
except User.DoesNotExist: | |
raise NotFound("user") | |
def user_is_artist(user_id): | |
artist_user = User.objects.get(id=user_id) | |
if Profile.objects.is_artist(artist_user): | |
return artist_user | |
return False | |
# def user_is_artist(user_id): | |
# try: | |
# artist_user = User.objects.get(id=user_id) | |
# if Profile.objects.is_artist(artist_user): | |
# return artist_user | |
# except ObjectDoesNotExist: | |
# pass | |
# return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
from datetime import timedelta | |
from django.utils import timezone | |
from django.conf import settings | |
import uuid | |
from django_countries.fields import CountryField | |
# Create your models here. | |
# Gig Name | |
# Number of Artists | |
# Date | |
# Genre (drop down) | |
# Location | |
# City | |
class GigPost(models.Model): | |
id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4) | |
gig_organizer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='organizer') | |
gig_name = models.CharField(max_length=255) | |
gig_artists = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='artists', through='Artists') | |
gig_creation_date = models.DateTimeField(auto_now_add=True) | |
gig_date = models.DateTimeField(auto_now=True) | |
gig_location_country = CountryField() | |
gig_location_city = models.CharField(max_length=100, null=False, blank=False) | |
gig_additional_info = models.TextField(null=True) | |
gig_banner = models.ImageField(upload_to='gigs', null=True, blank=True) | |
def __str__(self): | |
return self.gig_name | |
class Artists(models.Model): | |
PENDING = "pending" | |
ATTENDEES = "attendees" | |
id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4) | |
status = models.CharField( | |
verbose_name="status", | |
max_length=100, | |
choices=( | |
(PENDING, PENDING), | |
(ATTENDEES, ATTENDEES), | |
), | |
default=PENDING | |
) | |
applicant = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='artist') | |
gig = models.ForeignKey(GigPost, on_delete=models.CASCADE, related_name='event_many') | |
created = models.DateTimeField(auto_now_add=True, null=True, blank=True) | |
class Meta: | |
verbose_name_plural = "Artists" | |
def __str__(self): | |
return self.user.name + " - " + self.gig.gig_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from .models import * | |
from rest_framework.fields import UUIDField | |
# serialize the Gigs model | |
class GigSerializer(serializers.ModelSerializer): | |
id = serializers.PrimaryKeyRelatedField(read_only=True, | |
allow_null=False, | |
# This will properly serializes uuid.UUID to str: | |
pk_field=UUIDField(format='hex_verbose')) | |
gig_organizer = serializers.StringRelatedField(read_only=True) | |
gig_artists = serializers.StringRelatedField(read_only=True, many=True) | |
number_of_artists = serializers.SerializerMethodField() | |
class Meta: | |
model = GigPost | |
fields = ( | |
'id', | |
'gig_banner', | |
'gig_name', | |
'gig_organizer', | |
'gig_creation_date', | |
'gig_date', | |
'gig_location_country', | |
'gig_location_city', | |
'number_of_artists', | |
'gig_artists', | |
'gig_additional_info', | |
) | |
def get_number_of_artists(self, object): | |
return object.gig_artists.count() | |
class GigAttendanceSerializer(serializers.ModelSerializer): | |
id = serializers.PrimaryKeyRelatedField(read_only=True, | |
allow_null=False, | |
# This will properly serializes uuid.UUID to str: | |
pk_field=UUIDField(format='hex_verbose')) | |
user = serializers.PrimaryKeyRelatedField(read_only=True, pk_field=UUIDField(format='hex_verbose')) | |
gig=serializers.StringRelatedField() | |
class Meta: | |
model = Artists | |
fields = ( | |
'id', | |
'status' | |
'user', | |
'gig', | |
'created', | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.shortcuts import render | |
from rest_framework import viewsets, generics, status | |
from rest_framework.exceptions import PermissionDenied, ValidationError | |
from rest_framework.response import Response | |
from .models import * | |
from .permissions import IsConfirmedOrReadOnly, IsOrganizerOrReadOnly, IsArtist | |
from .serializers import (GigSerializer, GigAttendanceSerializer) | |
from wm_accounts.models import * | |
from wm_accounts.utils import user_is_artist | |
# Create your views here. | |
class GigViewSet(viewsets.ModelViewSet): | |
queryset = GigPost.objects.all() | |
serializer_class = GigSerializer | |
permission_classes = [IsOrganizerOrReadOnly] | |
def perform_create(self, serializer): | |
serializer.save(gig_organizer=self.request.user | |
def perform_destroy(self, instance): | |
Gig_instance = self.get_object() | |
user = self.request.user | |
gig_organizer = Gig_instance.gig_organizer | |
if user != gig_organizer: | |
raise ValidationError( | |
"Sorry you are not authorized to delete this Gig!") | |
# Gives 204 - No content. Frontend to show successfully deleted. | |
Gig_instance.delete() | |
# class ConfirmAttendanceViewSet(viewsets.ModelViewSet): | |
# queryset = Artists.objects.all() | |
# serializer_class = ConfirmAttendanceSerializer | |
# permission_classes = [IsArtist] | |
# def perform_create(self, serializer): | |
# print(self.request.data['gig']) | |
# attendance_queryset = Artists.objects.filter(gig=self.request.data['gig'], | |
# user=self.request.user) | |
# if attendance_queryset.exists(): | |
# raise ValidationError('you already booked this gig.') | |
# serializer.save(user=self.request.user) | |
# GIG REQUESTS FOR ARTISTS -> TO-DO | |
class SendGigRequest(generics.GenericAPIView): | |
serializer_class = GigAttendanceSerializer | |
lookup_url_kwarg = "gig_id" | |
def post(self, request, *args, **kwargs): | |
applicant = user_is_artist(self.request.user.id) | |
receiver_id = kwargs['gig_id'] | |
gig = GigPost.objects.get(id=receiver_id) | |
if applicant != gig.gig_organizer: | |
gig_request, created = Artists.objects.get_or_create( | |
applicant=self.request.user, gig=gig) | |
if created: | |
return Response(f"{self.request.user.name} sent a gig request to {gig.gig_name}") | |
else: | |
return Response(f"Hi {self.request.user.name}!, You have already sent a gig request to {gig.gig_name}") | |
return Response(f"Hi {self.request.user.name}!, You cannot send a gig request to your own gig") | |
# GET: List all open connect requests from others | |
# class ShowPendingReceivedGigRequests(ListAPIView): | |
# serializer_class = GigAttendanceSerializer | |
# def get_queryset(self): | |
# received_requests = GigAttendanceSerializer.objects.filter( | |
# status="pending", gig_id=self.request.user.id) | |
# return received_requests | |
# # GET: List all my pending connect requests | |
# class ShowPendingSentConnectRequests(ListAPIView): | |
# serializer_class = ConnectRequestSerializer | |
# def get_queryset(self): | |
# sent_requests = ConnectRequest.objects.filter( | |
# status="pending", sender_id=self.request.user.id) | |
# return sent_requests | |
# # POST: Accept an open connect request | |
# class AcceptConnectRequest(GenericAPIView): | |
# serializer_class = ConnectRequestSerializer | |
# lookup_url_kwarg = "request_id" | |
# def post(self, request, *args, **kwargs): | |
# request_id = kwargs["request_id"] | |
# try: | |
# connect_request = ConnectRequest.objects.get(id=request_id) | |
# sender = User.objects.get(id=connect_request.sender_id) | |
# receiver = User.objects.get(id=connect_request.receiver_id) | |
# if connect_request.status == "pending" and self.request.user.id == receiver.id: | |
# ConnectRequest.objects.create( | |
# sender=receiver, receiver=sender, status="connects") | |
# connect_request.status = "connects" | |
# connect_request.save() | |
# email = EmailMessage( | |
# subject=f"You have a new connect!", | |
# body=f"Hi {sender.name}\n\n{receiver.name} accepted your connect request!", | |
# from_email="[email protected]", | |
# to=[f"{sender.email}"], | |
# ) | |
# email.send() | |
# return Response(f"{sender.name} and {receiver.name} are now connects!") | |
# elif connect_request.status == "connects" and self.request.user.id == receiver.id: | |
# return Response(f"{sender.name} and {receiver.name} are already connects!") | |
# else: | |
# return Response(f"{self.request.user.name} is not part of this connect request.") | |
# except ConnectRequest.DoesNotExist: | |
# return Response(f"There is no connect request with ID {request_id}") | |
# # DELETE: Reject an open conenct request | |
# class RejectConnectRequest(GenericAPIView): | |
# serializer_class = ConnectRequestSerializer | |
# lookup_url_kwarg = "request_id" | |
# def delete(self, request, *args, **kwargs): | |
# request_id = kwargs["request_id"] | |
# connect_request = ConnectRequest.objects.get(id=request_id) | |
# current_user_id = self.request.user.id | |
# if connect_request.status == "pending" and connect_request.receiver_id == current_user_id: | |
# connect_request.delete() | |
# return Response("Connection request was rejected!") | |
# return Response(f"You have no pending conenction request with ID {request_id}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment