Refactor UserData admin interface; enhance user registration forms and validation; update Dockerfile for static files collection
parent
9d7305ef13
commit
c62d0deb33
|
|
@ -25,11 +25,9 @@ DEFAULT_AUTO_FIELD='django.db.models.AutoField'
|
|||
# Load the Env
|
||||
load_dotenv()
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = os.getenv('SECRET_KEY')
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
|
||||
|
||||
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com']
|
||||
|
||||
|
|
@ -40,7 +38,7 @@ INSTALLED_APPS = [
|
|||
'crispy_forms',
|
||||
'crispy_bootstrap4',
|
||||
'blog.apps.BlogConfig',
|
||||
'users.apps.UsersConfig',
|
||||
'users',
|
||||
'api.apps.APIConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
|
|
|
|||
|
|
@ -30,5 +30,5 @@ EXPOSE 3030
|
|||
# Define environment variable for Gunicorn
|
||||
ENV GUNICORN_CMD_ARGS="--bind 0.0.0.0:3030"
|
||||
|
||||
# Run Gunicorn server with your Django application
|
||||
CMD ["gunicorn", "BH.wsgi:application"]
|
||||
# Collect static files and run Gunicorn
|
||||
CMD ["sh", "-c", "python manage.py collectstatic --noinput && gunicorn BH.wsgi:application"]
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.9 on 2026-02-19 10:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('blog', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='blog',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
]
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mozilla+Headline" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
|
||||
<style type="text/css">
|
||||
:root {
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
|
||||
@font-face {
|
||||
font-family: 'Alte DIN 1451 Mittelschrift';
|
||||
src: url('mittelschrift.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */
|
||||
src: url('media/mittelschrift.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */
|
||||
}
|
||||
body {
|
||||
font-family: 'Alte DIN 1451 Mittelschrift', sans-serif;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
{% block content %}
|
||||
|
||||
{% load markdown_extras %}
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<br><br>
|
||||
<!-- Main Content -->
|
||||
<div class="container mt-5">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<br><br>
|
||||
<div class="container mt-5">
|
||||
<form method="POST">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<br><br>
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<br>
|
||||
<br>
|
||||
<div class="container mt-5">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
from django.contrib import admin
|
||||
from .models import *
|
||||
from .models import UserData
|
||||
|
||||
|
||||
admin.site.register(UserData)
|
||||
@admin.register(UserData)
|
||||
class UserDataAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'name', 'xp', 'money')
|
||||
search_fields = ('user__username', 'name')
|
||||
readonly_fields = ('user', 'xp', 'money', 'equipment', 'inventory')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from .models import *
|
||||
|
||||
|
||||
class UserRegisterForm(UserCreationForm):
|
||||
|
|
@ -11,6 +10,12 @@ class UserRegisterForm(UserCreationForm):
|
|||
model = User
|
||||
fields = ['username', 'email', 'password1', 'password2']
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data.get('email')
|
||||
if User.objects.filter(email__iexact=email).exists():
|
||||
raise forms.ValidationError('An account with this email address already exists.')
|
||||
return email.lower()
|
||||
|
||||
|
||||
class UserUpdateForm(forms.ModelForm):
|
||||
email = forms.EmailField()
|
||||
|
|
@ -19,3 +24,10 @@ class UserUpdateForm(forms.ModelForm):
|
|||
model = User
|
||||
fields = ['username', 'email']
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data.get('email')
|
||||
# Allow the current user to keep their own email
|
||||
if User.objects.filter(email__iexact=email).exclude(pk=self.instance.pk).exists():
|
||||
raise forms.ValidationError('An account with this email address already exists.')
|
||||
return email.lower()
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@ from django.contrib.auth.models import User
|
|||
class UserData(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=40)
|
||||
xp = models.IntegerField()
|
||||
money = models.IntegerField()
|
||||
equipment = models.CharField(max_length=1024, default='0;')
|
||||
inventory = models.CharField(max_length=1024, default='0;')
|
||||
|
||||
xp = models.IntegerField(default=0)
|
||||
money = models.IntegerField(default=10000)
|
||||
equipment = models.CharField(max_length=1024, default='0;', blank=True)
|
||||
inventory = models.CharField(max_length=1024, default='0;', blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username}'s data"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
from rest_framework import serializers
|
||||
from .models import *
|
||||
from .models import UserData
|
||||
|
||||
|
||||
class UserDataSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = UserData
|
||||
fields = ['user', 'name', 'xp', 'money', 'equipment', 'inventory']
|
||||
read_only_fields = ['user', 'xp', 'money', 'equipment', 'inventory']
|
||||
|
|
|
|||
|
|
@ -1,54 +1,12 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.models import User
|
||||
from django.views.generic import ListView
|
||||
from .forms import UserRegisterForm
|
||||
from blog.models import *
|
||||
from .models import *
|
||||
from django.views.generic import *
|
||||
|
||||
|
||||
# Create your views here.
|
||||
# def users(request):
|
||||
# return render(request, 'users/users.html', {'title': 'Users'})
|
||||
|
||||
# def getFromArr(arr, indices, *args, **kwargs):
|
||||
# x = []
|
||||
# for i in indices:
|
||||
# x.append(arr[i])
|
||||
# return x
|
||||
|
||||
|
||||
# @login_required
|
||||
# def profile(request, *args, **kwargs):
|
||||
# try:
|
||||
# user = User._default_manager.all()[kwargs['pk'] - 1]
|
||||
# except:
|
||||
# user = request.user
|
||||
# print(user.id)
|
||||
|
||||
# allow_empty = True
|
||||
# queryset = Post._default_manager.all()
|
||||
# context_object_name = 'posts'
|
||||
# ordering = ['-date_posted']
|
||||
|
||||
# if ordering:
|
||||
# if isinstance(ordering, str):
|
||||
# ordering = (ordering,)
|
||||
# queryset = queryset.order_by(*ordering)
|
||||
|
||||
# return render(request, 'users/profile.html', {'title': 'Profile', 'profileUser': user, context_object_name: queryset})
|
||||
|
||||
|
||||
# def people(request):
|
||||
# return render(request, 'users/people.html', {'title': 'People', 'users': User._default_manager.all()})
|
||||
|
||||
|
||||
users = {
|
||||
'user': User.objects.all()
|
||||
}
|
||||
|
||||
|
||||
class UserListView(ListView):
|
||||
class UserListView(LoginRequiredMixin, ListView):
|
||||
model = User
|
||||
template_name = 'users/people.html'
|
||||
context_object_name = 'users'
|
||||
|
|
|
|||
Loading…
Reference in New Issue