diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/admin.py b/core/admin.py new file mode 100644 index 0000000..905eff4 --- /dev/null +++ b/core/admin.py @@ -0,0 +1,39 @@ +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin + +from .forms import CustomUserCreationForm +from .models import Product, User + + +# Register your models here. +class CustomUserAdmin(UserAdmin): + list_filter = ["plans"] + model = User + add_form = CustomUserCreationForm + fieldsets = ( + *UserAdmin.fieldsets, + ( + "Stripe information", + { + "fields": ( + "stripe_id", + "subscription_id", + ) + }, + ), + ( + "Payment information", + { + "fields": ( + "subscription_active", + "paid", + "plans", + "last_payment", + ) + }, + ), + ) + + +admin.site.register(User, CustomUserAdmin) +admin.site.register(Product) diff --git a/core/apps.py b/core/apps.py new file mode 100644 index 0000000..c0ce093 --- /dev/null +++ b/core/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "core" diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..5392800 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,34 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm + +from .models import User + +# Create your forms here. + + +class NewUserForm(UserCreationForm): + email = forms.EmailField(required=True) + + class Meta: + model = User + fields = ( + "username", + "email", + "first_name", + "last_name", + "password1", + "password2", + ) + + def save(self, commit=True): + user = super(NewUserForm, self).save(commit=False) + user.email = self.cleaned_data["email"] + if commit: + user.save() + return user + + +class CustomUserCreationForm(UserCreationForm): + class Meta: + model = User + fields = "__all__" diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..fdeb481 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,157 @@ +# Generated by Django 4.0.6 on 2022-07-05 12:45 + +import django.contrib.auth.models +import django.contrib.auth.validators +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ] + + operations = [ + migrations.CreateModel( + name="Product", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("description", models.CharField(max_length=1024, null=True)), + ("cost", models.IntegerField()), + ("product_id", models.UUIDField(null=True)), + ("image", models.CharField(max_length=1024, null=True)), + ], + ), + migrations.CreateModel( + name="User", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("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" + ), + ), + ("stripe_id", models.CharField(max_length=255, null=True)), + ("subscription_id", models.CharField(max_length=255, null=True)), + ("subscription_active", models.BooleanField(null=True)), + ("last_payment", models.DateTimeField(null=True)), + ("paid", models.BooleanField(null=True)), + ( + "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", + ), + ), + ("plans", models.ManyToManyField(to="core.product")), + ( + "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()), + ], + ), + ] diff --git a/core/migrations/__init__.py b/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/models.py b/core/models.py new file mode 100644 index 0000000..f938102 --- /dev/null +++ b/core/models.py @@ -0,0 +1,29 @@ +from django.contrib.auth.models import AbstractUser +from django.db import models + +# Create your models here. + + +class Product(models.Model): + name = models.CharField(max_length=255) + description = models.CharField(max_length=1024) + cost = models.IntegerField() + product_id = models.UUIDField(blank=True) + image = models.CharField(max_length=1024, blank=True) + + def __str__(self): + return f"{self.name} (£{self.cost})" + + +class User(AbstractUser): + # Stripe customer ID + stripe_id = models.CharField(max_length=255, blank=True) + subscription_id = models.CharField(max_length=255, blank=True) + subscription_active = models.BooleanField(blank=True) + last_payment = models.DateTimeField(blank=True) + paid = models.BooleanField(blank=True) + plans = models.ManyToManyField(Product, blank=True) + + def has_plan(self, plan): + plan_list = [plan.name for plan in self.plans.all()] + return plan in plan_list diff --git a/core/tests.py b/core/tests.py new file mode 100644 index 0000000..a79ca8b --- /dev/null +++ b/core/tests.py @@ -0,0 +1,3 @@ +# from django.test import TestCase + +# Create your tests here. diff --git a/core/views.py b/core/views.py new file mode 100644 index 0000000..1185288 --- /dev/null +++ b/core/views.py @@ -0,0 +1,29 @@ +from django.contrib.auth.mixins import LoginRequiredMixin +from django.shortcuts import render +from django.urls import reverse_lazy +from django.views import View +from django.views.generic.edit import CreateView + +from core.forms import NewUserForm + +# Create your views here + + +class Home(LoginRequiredMixin, View): + template_name = "index.html" + + def get(self, request, *args, **kwargs): + return render(request, self.template_name) + + +class Profile(LoginRequiredMixin, View): + template_name = "profile.html" + + def get(self, request, *args, **kwargs): + return render(request, self.template_name) + + +class Signup(CreateView): + form_class = NewUserForm + success_url = reverse_lazy("login") + template_name = "registration/signup.html"