Skip to content

Instantly share code, notes, and snippets.

@pmburu
Created March 3, 2020 19:25
Show Gist options
  • Save pmburu/a0d31b5d9aa49fbc5eaecaa262c45478 to your computer and use it in GitHub Desktop.
Save pmburu/a0d31b5d9aa49fbc5eaecaa262c45478 to your computer and use it in GitHub Desktop.
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')
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()
# 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
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
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',
)
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