base to work with

stream
Laurent 2 years ago
parent 5dc2d69142
commit 731eb50559
  1. 4
      .gitignore
  2. 20
      padelclub_backend/settings.py
  3. 13
      padelclub_backend/urls.py
  4. 27
      tournaments/admin.py
  5. 14
      tournaments/forms.py
  6. 47
      tournaments/migrations/0001_initial.py
  7. 21
      tournaments/models.py
  8. 54
      tournaments/serializers.py
  9. 50
      tournaments/views.py

4
.gitignore vendored

@ -4,6 +4,10 @@ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
.DS_Store
*/.DS_Store
**/*/.DS*
# C extensions # C extensions
*.so *.so

@ -32,16 +32,19 @@ ALLOWED_HOSTS = ['*']
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"tournaments.apps.TournamentsConfig", 'tournaments',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'rest_framework' 'rest_framework',
'rest_framework.authtoken',
] ]
AUTH_USER_MODEL = "tournaments.CustomUser"
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
@ -136,3 +139,16 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Rest Framework configuration
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
# 'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
# ],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.TokenAuthentication',
]
}

@ -1,4 +1,4 @@
"""padelclub_backend URL Configuration """storage_poc URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see: The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/ https://docs.djangoproject.com/en/4.1/topics/http/urls/
@ -14,17 +14,22 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import include, path
from tournaments import views
from rest_framework import routers from rest_framework import routers
from tournaments import views
from rest_framework.authtoken.views import obtain_auth_token
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet) router.register(r'users', views.UserViewSet)
router.register(r'clubs', views.ClubViewSet) router.register(r'clubs', views.ClubViewSet)
router.register(r'tournaments', views.TournamentViewSet)
urlpatterns = [ urlpatterns = [
path('api/', include(router.urls)), path('api/', include(router.urls)),
path("tournaments/", include("tournaments.urls")), path("tournaments/", include("tournaments.urls")),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('api/plus/api-token-auth/', obtain_auth_token, name='api_token_auth'),
path("api/plus/user-by-token/", views.user_by_token, name="user_by_token"),
path("api/plus/change-password/", views.ChangePasswordView.as_view(), name="change_password"),
] ]

@ -1,6 +1,29 @@
from django.contrib import admin from django.contrib import admin
from .models import Club, Tournament
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
# Register your models here. from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import Club from .models import CustomUser
class CustomUserAdmin(UserAdmin):
form = CustomUserChangeForm
add_form = CustomUserCreationForm
model = CustomUser
list_display = ["email", "username", "umpire_code"]
fieldsets = [
(None, {"fields": ["username", "email", "password", "club", "umpire_code"]}),
]
add_fieldsets = [
(
None,
{
"classes": ["wide"],
"fields": ["username", "email", "password1", "password2", "club", "umpire_code"],
},
),
]
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.register(Club) admin.site.register(Club)
admin.site.register(Tournament)

@ -0,0 +1,14 @@
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = UserCreationForm.Meta.fields + ("umpire_code", )
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = UserCreationForm.Meta.fields + ("umpire_code", )

@ -1,6 +1,11 @@
# Generated by Django 4.1.1 on 2024-01-19 10:42 # Generated by Django 4.1.1 on 2024-02-23 09:08
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import uuid
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -8,14 +13,52 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Club', name='Club',
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('name', models.CharField(max_length=200)), ('name', models.CharField(max_length=200)),
('address', models.CharField(blank=True, max_length=200, null=True)),
],
),
migrations.CreateModel(
name='Tournament',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=200)),
('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.club')),
],
),
migrations.CreateModel(
name='CustomUser',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('umpire_code', models.CharField(blank=True, max_length=200, null=True)),
('club', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='tournaments.club')),
('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='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
], ],
), ),
] ]

@ -1,6 +1,27 @@
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser
import uuid
class Club(models.Model): class Club(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
name = models.CharField(max_length=200)
address = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return self.name
class CustomUser(AbstractUser):
pass
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
umpire_code = models.CharField(max_length=200, blank=True, null=True)
club = models.ForeignKey(Club, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.username
class Tournament(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
club = models.ForeignKey(Club, on_delete=models.CASCADE)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
def __str__(self): def __str__(self):

@ -1,13 +1,57 @@
from django.contrib.auth.models import User
from rest_framework import serializers from rest_framework import serializers
from .models import Club from .models import Club, Tournament, CustomUser
from django.contrib.auth import password_validation
from django.utils.translation import gettext_lazy as _
class UserSerializer(serializers.HyperlinkedModelSerializer): class UserSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(write_only=True)
def create(self, validated_data):
user = CustomUser.objects.create_user(
username=validated_data['username'],
password=validated_data['password'],
)
return user
class Meta: class Meta:
model = User club_id = serializers.PrimaryKeyRelatedField(queryset=Club.objects.all())
fields = ['url', 'username', 'email'] model = CustomUser
fields = ['id', 'username', 'password', 'club_id', 'umpire_code']
class ClubSerializer(serializers.HyperlinkedModelSerializer): class ClubSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = Club model = Club
fields = ['id', 'name'] fields = ['id', 'name', 'address']
class TournamentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
club_id = serializers.PrimaryKeyRelatedField(queryset=Club.objects.all())
model = Tournament
fields = ['id', 'name', 'club_id']
class ChangePasswordSerializer(serializers.Serializer):
old_password = serializers.CharField(max_length=128, write_only=True, required=True)
new_password1 = serializers.CharField(max_length=128, write_only=True, required=True)
new_password2 = serializers.CharField(max_length=128, write_only=True, required=True)
def validate_old_password(self, value):
user = self.context['request'].user
if not user.check_password(value):
raise serializers.ValidationError(
_('Your old password was entered incorrectly. Please enter it again.')
)
return value
def validate(self, data):
if data['new_password1'] != data['new_password2']:
raise serializers.ValidationError({'new_password2': _("The two password fields didn't match.")})
password_validation.validate_password(data['new_password1'], self.context['request'].user)
return data
def save(self, **kwargs):
password = self.validated_data['new_password1']
user = self.context['request'].user
user.set_password(password)
user.save()
return user

@ -1,26 +1,48 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse
from .serializers import ClubSerializer, TournamentSerializer, UserSerializer, ChangePasswordSerializer
from .models import Club, Tournament, CustomUser
from rest_framework import viewsets, permissions from rest_framework import viewsets, permissions
from django.contrib.auth.models import User from rest_framework.authtoken.models import Token
from .serializers import UserSerializer, ClubSerializer from rest_framework.response import Response
from .models import Club from rest_framework.decorators import api_view
from rest_framework import status
from rest_framework.generics import UpdateAPIView
def index(request): def index(request):
return HttpResponse("Hello, world. You're at the tournaments index.") return HttpResponse("Hello, you're at the top of the world.")
@api_view(['GET'])
def user_by_token(request):
# return Response({"message": "Hello for today! See you tomorrow!"})
# key = request.data['token']
# token = Token.objects.get(key=key)
# user = CustomUser.objects.get(username=token.user)
serializer = UserSerializer(request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
class UserViewSet(viewsets.ModelViewSet): class UserViewSet(viewsets.ModelViewSet):
""" queryset = CustomUser.objects.all()
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
class ClubViewSet(viewsets.ModelViewSet): class ClubViewSet(viewsets.ModelViewSet):
""" queryset = Club.objects.all()
API endpoint that allows clubs to be viewed or edited.
"""
queryset = Club.objects.all().order_by('id')
serializer_class = ClubSerializer serializer_class = ClubSerializer
permission_classes = [permissions.IsAuthenticated]
class TournamentViewSet(viewsets.ModelViewSet):
queryset = Tournament.objects.all()
serializer_class = TournamentSerializer
class ChangePasswordView(UpdateAPIView):
serializer_class = ChangePasswordSerializer
def update(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
# if using drf authtoken, create a new token
if hasattr(user, 'auth_token'):
user.auth_token.delete()
token, created = Token.objects.get_or_create(user=user)
# return new token
return Response({'token': token.key}, status=status.HTTP_200_OK)

Loading…
Cancel
Save