Added UserData to the API

with_posts_new
Surya 2026-02-28 18:50:48 +05:30
parent 982216767b
commit d774f2f93c
15 changed files with 137 additions and 56 deletions

3
.gitignore vendored
View File

@ -163,3 +163,6 @@ cython_debug/
# static # static
staticfiles/ staticfiles/
# database
db.sqlite3

View File

@ -24,7 +24,7 @@ TEMPLATES_DIR = os.path.join(BASE_DIR + '/templates')
SECRET_KEY = '!2g)+m+_h9fq9%il5+t5#qnj^9502or6$=2!$==v=i2*c#7q*m' SECRET_KEY = '!2g)+m+_h9fq9%il5+t5#qnj^9502or6$=2!$==v=i2*c#7q*m'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False DEBUG = True
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com'] ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com']
@ -127,7 +127,7 @@ REST_FRAMEWORK = {
'rest_framework.permissions.IsAuthenticated', 'rest_framework.permissions.IsAuthenticated',
], ],
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
# 'rest_framework.authentication.SessionAuthentication', # causes CSRF Token conflicts in API 'rest_framework.authentication.SessionAuthentication', # causes CSRF Token conflicts in API
'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.TokenAuthentication',
) )
} }
@ -161,6 +161,6 @@ LOGIN_REDIRECT_URL = 'Home'
LOGIN_URL = 'Login' LOGIN_URL = 'Login'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # prints to console EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # prints to console
# SITE_ID = 1 # for django-allauth SITE_ID = 1 # for django-allauth
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

8
api/filters.py Normal file
View File

@ -0,0 +1,8 @@
from rest_framework.filters import BaseFilterBackend
from users.models import *
class UserDataFilterBackend(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
queryset = queryset.filter(user__id=request.user.id)
return queryset

View File

@ -10,3 +10,15 @@ class IsSuperUserOrReadOnly(permissions.BasePermission):
class IsStaff(permissions.BasePermission): class IsStaff(permissions.BasePermission):
def has_permission(self, request, view): def has_permission(self, request, view):
return request.user.is_staff return request.user.is_staff
class IsSuperUserOrAuthReadOnly(permissions.BasePermission):
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS:
return request.user != None
return request.user.is_superuser
class IsSuperUser(permissions.BasePermission):
def has_permission(self, request, view):
return request.user.is_superuser

View File

@ -10,7 +10,7 @@ class ProvinceSerializer(serializers.ModelSerializer):
class AssaultTroopSerializer(serializers.ModelSerializer): class AssaultTroopSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = AssaultTroop model = AssaultTroop
fields = ['id', 'name', 'faction', 'type', 'province', 'deployed', 'orders', 'owner'] fields = ['id', 'name', 'faction', 'type', 'province', 'orders', 'owner']
class PlayerSerializer(serializers.ModelSerializer): class PlayerSerializer(serializers.ModelSerializer):

View File

@ -10,4 +10,6 @@ urlpatterns = [
path('players/<int:nm>/', PlayerView.as_view()), path('players/<int:nm>/', PlayerView.as_view()),
path('servers/', ServersView.as_view()), path('servers/', ServersView.as_view()),
path('servers/<int:nm>/', ServerView.as_view()), path('servers/<int:nm>/', ServerView.as_view()),
path('user_data/', UserDataView.as_view()),
path('user_data/<int:pk>/', UserDatumView.as_view()),
] ]

View File

@ -1,48 +1,75 @@
from rest_framework import generics, permissions from rest_framework import generics, permissions
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from .models import * from .models import *
from .filters import *
from .serializers import * from .serializers import *
from .permissions import * from .permissions import *
from users.models import *
from users.serializers import *
@method_decorator(csrf_exempt, name='dispatch')
class ProvincesView(generics.ListCreateAPIView): class ProvincesView(generics.ListCreateAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = Province.objects.all() queryset = Province.objects.all()
serializer_class = ProvinceSerializer serializer_class = ProvinceSerializer
@method_decorator(csrf_exempt, name='dispatch')
class ProvinceView(generics.RetrieveUpdateDestroyAPIView): class ProvinceView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = Province.objects.all() queryset = Province.objects.all()
serializer_class = ProvinceSerializer serializer_class = ProvinceSerializer
@method_decorator(csrf_exempt, name='dispatch')
class AssaultTroopsView(generics.ListCreateAPIView): class AssaultTroopsView(generics.ListCreateAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = AssaultTroop.objects.all() queryset = AssaultTroop.objects.all()
serializer_class = AssaultTroopSerializer serializer_class = AssaultTroopSerializer
@method_decorator(csrf_exempt, name='dispatch')
class AssaultTroopView(generics.RetrieveUpdateDestroyAPIView): class AssaultTroopView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = AssaultTroop.objects.all() queryset = AssaultTroop.objects.all()
serializer_class = AssaultTroopSerializer serializer_class = AssaultTroopSerializer
@method_decorator(csrf_exempt, name='dispatch')
class PlayersView(generics.ListCreateAPIView): class PlayersView(generics.ListCreateAPIView):
permission_classes = (IsStaff,) # Only Staff can see player info, i.e. authorized servers permission_classes = (IsStaff,) # Only Staff can see player info, i.e. authorized servers
queryset = Player.objects.all() queryset = Player.objects.all()
serializer_class = PlayerSerializer serializer_class = PlayerSerializer
@method_decorator(csrf_exempt, name='dispatch')
class PlayerView(generics.RetrieveUpdateDestroyAPIView): class PlayerView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsStaff) permission_classes = (IsStaff)
queryset = Player.objects.all() queryset = Player.objects.all()
serializer_class = PlayerSerializer serializer_class = PlayerSerializer
@method_decorator(csrf_exempt, name='dispatch')
class ServersView(generics.ListCreateAPIView): class ServersView(generics.ListCreateAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = Server.objects.all() queryset = Server.objects.all()
serializer_class = ServerSerializer serializer_class = ServerSerializer
@method_decorator(csrf_exempt, name='dispatch')
class ServerView(generics.RetrieveUpdateDestroyAPIView): class ServerView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsSuperUserOrReadOnly,) permission_classes = (IsSuperUserOrReadOnly,)
queryset = Server.objects.all() queryset = Server.objects.all()
serializer_class = ServerSerializer serializer_class = ServerSerializer
@method_decorator(csrf_exempt, name='dispatch')
class UserDatumView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsSuperUser,)
queryset = UserData.objects.all()
serializer_class = UserDataSerializer
# filter_backends = [UserDataFilterBackend]
@method_decorator(csrf_exempt, name='dispatch')
class UserDataView(generics.ListCreateAPIView):
permission_classes = (IsSuperUserOrAuthReadOnly,)
queryset = UserData.objects.all()
serializer_class = UserDataSerializer
filter_backends = [UserDataFilterBackend]

Binary file not shown.

View File

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Profile from .models import *
# Register your models here. admin.site.register(UserData)

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm
from .models import Profile from .models import *
class UserRegisterForm(UserCreationForm): class UserRegisterForm(UserCreationForm):

View File

@ -0,0 +1,31 @@
# Generated by Django 5.2.9 on 2026-02-28 03:45
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0002_alter_profile_id'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='UserData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=40)),
('xp', models.IntegerField()),
('money', models.IntegerField()),
('equipment', models.CharField(default='0;', max_length=1024)),
('inventory', models.CharField(default='0;', max_length=1024)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.DeleteModel(
name='Profile',
),
]

View File

@ -3,14 +3,21 @@ from django.contrib.auth.models import User
# Create your models here. # Create your models here.
class Profile(models.Model): class UserData(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100) name = models.CharField(max_length=40)
about = models.TextField(default='Hi, I am new to TechBlog') xp = models.IntegerField()
gender = models.TextField(default='None') money = models.IntegerField()
dob = models.DateField(default='1999-01-01') equipment = models.CharField(max_length=1024, default='0;')
# image = models.ImageField(default='default.png', name='profile_pic', upload_to='profile_pics') inventory = models.CharField(max_length=1024, default='0;')
def __str__(self): def __str__(self):
return f"{self.user.username}'s Profile" return f"{self.user.username}'s data"
# So this is my beutiful brainchild to keep user data in about 1KB per user, I'm not too sure but still
# it's worth the try, so the main payload is the inventory along the soliers an their weapons and vehicles
# along with the mods for everything which I have separated by `;`, `.` and `,` for soldier, equipment
# class and each equipment. I'll try a bit of bit-hacking to pack as much info of 20 bytes in 2 of the mods.
# ammo|--|sights|---|internals|---|, trigger|--|barrel|--|skins|----|, number|--------|

7
users/serializers.py Normal file
View File

@ -0,0 +1,7 @@
from rest_framework import serializers
from .models import *
class UserDataSerializer(serializers.ModelSerializer):
class Meta:
model = UserData
fields = ['user', 'name', 'xp', 'money', 'equipment', 'inventory']

View File

@ -3,8 +3,8 @@ from django.contrib.auth import views as login_view
from . import views from . import views
urlpatterns = [ urlpatterns = [
path('profile/', views.profile, name='Profile'), # path('profile/', views.profile, name='Profile'),
path('profile/<int:pk>', views.profile, name='NamedProfile'), # path('profile/<int:pk>', views.profile, name='NamedProfile'),
path('login/', login_view.LoginView.as_view(template_name='users/login.html'), name='Login'), path('login/', login_view.LoginView.as_view(template_name='users/login.html'), name='Login'),
path('logout/', login_view.LogoutView.as_view(template_name='users/logout.html'), name='Logout'), path('logout/', login_view.LogoutView.as_view(template_name='users/logout.html'), name='Logout'),
path('register/', views.register, name='Register') path('register/', views.register, name='Register')

View File

@ -11,52 +11,36 @@ from django.views.generic import *
# def users(request): # def users(request):
# return render(request, 'users/users.html', {'title': 'Users'}) # return render(request, 'users/users.html', {'title': 'Users'})
def getFromArr(arr, indices, *args, **kwargs): # def getFromArr(arr, indices, *args, **kwargs):
x = [] # x = []
for i in indices: # for i in indices:
x.append(arr[i]) # x.append(arr[i])
return x # return x
@login_required # @login_required
def profile(request, *args, **kwargs): # def profile(request, *args, **kwargs):
try: # try:
user = User._default_manager.all()[kwargs['pk'] - 1] # user = User._default_manager.all()[kwargs['pk'] - 1]
except: # except:
user = request.user # user = request.user
print(user.id) # print(user.id)
allow_empty = True # allow_empty = True
queryset = None # queryset = Post._default_manager.all()
model = Post # context_object_name = 'posts'
paginate_by = None # ordering = ['-date_posted']
paginate_orphans = 0
context_object_name = 'posts'
ordering = ['-date_posted']
if queryset is not None: # if ordering:
queryset = queryset # if isinstance(ordering, str):
if isinstance(queryset, QuerySet): # ordering = (ordering,)
queryset = queryset.all() # queryset = queryset.order_by(*ordering)
elif model is not None:
queryset = model._default_manager.all()
else:
raise ImproperlyConfigured(
"%(cls)s is missing a QuerySet. Define "
"%(cls)s.model, %(cls)s.queryset, or override "
"%(cls)s.get_queryset()." % {"cls": self.__class__.__name__}
)
if ordering: # return render(request, 'users/profile.html', {'title': 'Profile', 'profileUser': user, context_object_name: queryset})
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): # def people(request):
return render(request, 'users/people.html', {'title': 'People', 'users': User._default_manager.all()}) # return render(request, 'users/people.html', {'title': 'People', 'users': User._default_manager.all()})
users = { users = {