added team members

This commit is contained in:
mi1468 2025-05-21 16:53:48 +03:30
parent 27c3b42d62
commit 255441ad61
15 changed files with 355 additions and 128 deletions

View File

@ -1,11 +1,13 @@
from django.contrib import admin
from core.models.customer import Customer
from core.models.Subscription import Subscription
from core.models.role import Role
from core.models.image import Image
from core.models.video import Video
from core.models.glb import Glb
from core.models.pdf import Pdf
from core.models.TeamMember import TeamMember
# from .model import user
from core.models.AssignedRule import AssignedRule
@ -17,3 +19,5 @@ admin.site.register(Glb)
admin.site.register(Role)
admin.site.register(AssignedRule)
admin.site.register(Customer)
admin.site.register(Subscription)
admin.site.register(TeamMember)

View File

@ -1,4 +1,4 @@
# Generated by Django 5.0 on 2025-04-12 14:25
# Generated by Django 5.0 on 2025-05-21 07:58
import django.db.models.deletion
from django.conf import settings
@ -25,9 +25,10 @@ class Migration(migrations.Migration):
name='Customer',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('profile_img', models.CharField(max_length=255)),
('profile_glb', models.CharField(max_length=255)),
('semat', models.CharField(blank=True, max_length=255)),
('mobile_number', models.CharField(max_length=15)),
('profile_img', models.CharField(blank=True, max_length=255)),
('profile_glb', models.CharField(blank=True, max_length=255)),
('verification_sms_code', models.CharField(blank=True, max_length=6)),
('verification_email_code', models.CharField(blank=True, max_length=6)),
('is_sms_verified', models.BooleanField(default=False)),
@ -36,6 +37,39 @@ class Migration(migrations.Migration):
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Glb',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('glb', models.FileField(blank=True, null=True, upload_to='user_glbs/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Image',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('image', models.ImageField(blank=True, null=True, upload_to='user_images/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Pdf',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('pdf', models.FileField(blank=True, null=True, upload_to='user_pdfs/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='AssignedRule',
fields=[
@ -44,4 +78,27 @@ class Migration(migrations.Migration):
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.role')),
],
),
migrations.CreateModel(
name='Subscription',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('license_number', models.CharField(max_length=100)),
('user_count', models.PositiveIntegerField(blank=True, default=0)),
('startTime', models.DateTimeField()),
('endTime', models.DateTimeField()),
('price', models.DecimalField(decimal_places=2, max_digits=30)),
('user', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Video',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('video', models.FileField(blank=True, null=True, upload_to='user_videos/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 5.0 on 2025-04-12 14:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='customer',
name='profile_glb',
field=models.CharField(blank=True, max_length=255),
),
migrations.AlterField(
model_name='customer',
name='profile_img',
field=models.CharField(blank=True, max_length=255),
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 5.0 on 2025-05-21 12:48
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='TeamMember',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('isAdmin', models.BooleanField(default=False)),
('adminUser', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='admin_user', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'adminUser')},
},
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.0 on 2025-04-13 11:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0002_alter_customer_profile_glb_and_more'),
]
operations = [
migrations.AddField(
model_name='customer',
name='name',
field=models.CharField(blank=True, max_length=255),
),
]

View File

@ -1,31 +0,0 @@
# Generated by Django 5.0 on 2025-04-19 10:02
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0003_customer_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RemoveField(
model_name='customer',
name='name',
),
migrations.CreateModel(
name='Image',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('image', models.ImageField(blank=True, null=True, upload_to='user_images/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,49 +0,0 @@
# Generated by Django 5.0 on 2025-04-19 11:42
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0004_remove_customer_name_image'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Glb',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('glb', models.ImageField(blank=True, null=True, upload_to='user_glbs/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Pdf',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('pdf', models.ImageField(blank=True, null=True, upload_to='user_pdfs/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Video',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.URLField(blank=True, max_length=250)),
('video', models.ImageField(blank=True, null=True, upload_to='user_videos/')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

Binary file not shown.

View File

@ -0,0 +1,24 @@
from django.db import models
from django.conf import settings
class Subscription(models.Model):
# uid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE)
license_number = models.CharField(max_length=100)
user_count = models.PositiveIntegerField(default = 0,blank=True) # changed from license_number CharField
startTime = models.DateTimeField()
endTime = models.DateTimeField()
price = models.DecimalField(max_digits=30, decimal_places=2)
def __str__(self):
return f"Subscription {self.user_count} - License: {self.license_number}"

13
core/models/TeamMember.py Normal file
View File

@ -0,0 +1,13 @@
from django.db import models
from django.conf import settings
class TeamMember(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='user', on_delete=models.CASCADE)
adminUser = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='admin_user', on_delete=models.CASCADE)
isAdmin = models.BooleanField(default=False)
def __str__(self):
return f"TeamMember {self.user} - Admin: {self.isAdmin}"
class Meta:
unique_together = ('user', 'adminUser') # Ensure that one user can be added only once per admin

View File

@ -0,0 +1,21 @@
from rest_framework import serializers
from core.models.Subscription import Subscription
class SubscriptionSerializer(serializers.ModelSerializer):
class Meta:
model = Subscription
fields = ['user', 'license_number', 'user_count', 'startTime', 'endTime', 'price']
read_only_fields = ['user'] # user will be set automatically by the view
def create(self, validated_data):
"""
Override the create method to ensure the user is assigned automatically.
This is important since 'user' is not part of the data coming from the client
but is assigned based on the authenticated user.
"""
# The user is automatically added by the view (request.user)
user = validated_data.pop('user', None) # We do not expect user to be passed from the client
subscription = Subscription.objects.create(**validated_data, user=user)
return subscription

View File

@ -0,0 +1,16 @@
from rest_framework import serializers
from core.models.TeamMember import TeamMember
class TeamMemberSerializer(serializers.ModelSerializer):
class Meta:
model = TeamMember
fields = ['user', 'adminUser', 'isAdmin']
read_only_fields = ['adminUser']
def create(self, validated_data):
"""
Override the create method to automatically assign the admin user (request.user).
"""
admin_user = validated_data.pop('adminUser', None)
team_member = TeamMember.objects.create(adminUser=self.context['request'].user, **validated_data)
return team_member

View File

@ -44,7 +44,11 @@ urlpatterns = [
re_path('uploadGlb/', userView.upload_glb , name='upload_glb'),
re_path('uploadVideo/', userView.upload_video , name='upload_video'),
re_path('uploadPdf/', userView.upload_pdf , name='upload_pdf'),
re_path('add_subscription', userView.addSubscription),
re_path('add_teamMember', userView.addTeamMember),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -20,6 +20,8 @@ from core.serializers.ImageSerializer import ImageSerializer
from core.serializers.GlbSerializer import GlbSerializer
from core.serializers.VideoSerializer import VideoSerializer
from core.serializers.PdfSerializer import PdfSerializer
from core.serializers.SubscriptionSerializer import SubscriptionSerializer
from core.serializers.TeamMemberSerializer import TeamMemberSerializer
# utils.py
from core.models.AssignedRule import AssignedRule
@ -27,7 +29,7 @@ from core.models.image import Image
from core.models.video import Video
from core.models.pdf import Pdf
from core.models.glb import Glb
from core.models.Subscription import Subscription
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
@ -122,6 +124,9 @@ def signup(request):
else:
return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
def sendForgetPasswordCode(request):
try:
@ -315,12 +320,16 @@ def getInfo(request):
user_videos = Video.objects.filter(user=user).order_by('-created_at')
user_glbs = Glb.objects.filter(user=user).order_by('-created_at')
user_subscriptions = Subscription.objects.filter(user=user)
customer_serializer = CustomerSerializer(customer)
image_serializer = ImageSerializer(user_images, many=True)
pdf_serializer = PdfSerializer(user_pdfs, many=True)
video_serializer = VideoSerializer(user_videos, many=True)
glb_serializer = GlbSerializer(user_glbs, many=True)
subscription_serializer = SubscriptionSerializer(user_subscriptions, many=True)
user_data = {
'id': user.id,
'first_name': user.first_name,
@ -336,6 +345,7 @@ def getInfo(request):
'pdfs': pdf_serializer.data,
'videos': video_serializer.data,
'glbs': glb_serializer.data,
'subscription': subscription_serializer.data,
},
'message': 'موفق'
}, status=status.HTTP_200_OK)
@ -947,4 +957,166 @@ def verifyResetCode(request):
return Response(
{'success': False, 'message': f'Error resetting password: {str(e)}'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
)
@api_view(['POST'])
@authentication_classes([SessionAuthentication, TokenAuthentication])
@permission_classes([IsAuthenticated])
def addSubscription(request):
# Make a mutable copy of the request data
data = request.data.copy()
data['user'] = request.user.id # Automatically assign the authenticated user
# Deserialize and validate the incoming data
serializer = SubscriptionSerializer(data=data)
if serializer.is_valid():
# Save the subscription using the validated data
subscription = serializer.save(user=request.user) # This automatically saves the subscription
# Return the response with the subscription data
return Response({
"message": "Subscription created successfully.",
"subscription": serializer.data # This gives you the serialized data of the saved subscription
}, status=status.HTTP_201_CREATED)
else:
# If validation fails, return the errors
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# @api_view(['POST'])
# @authentication_classes([SessionAuthentication, TokenAuthentication])
# @permission_classes([IsAuthenticated])
# def addTeamMember(request):
# # Make a mutable copy of the request data
# data = request.data.copy()
# data['adminUser'] = request.user.id # Automatically assign the authenticated user as admin
# # Pass the request object to the serializer context
# serializer = TeamMemberSerializer(data=data, context={'request': request})
# if serializer.is_valid():
# # Save the team member using the validated data
# team_member = serializer.save() # This automatically saves the team member
# # Return the response with the team member data
# return Response({
# "message": "Team member added successfully.",
# "team_member": serializer.data # This gives you the serialized data of the saved team member
# }, status=status.HTTP_201_CREATED)
# else:
# # If validation fails, return the errors
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@authentication_classes([SessionAuthentication, TokenAuthentication])
@permission_classes([IsAuthenticated])
def addTeamMember(request):
# Check if username already exists
if User.objects.filter(username=request.data['mobile_number']).exists():
return Response({'username': ['A user with that username already exists.']}, status=status.HTTP_400_BAD_REQUEST)
# Ensure mobile number is provided
if 'mobile_number' not in request.data:
return Response({'mobile_number': ['This field is required.']}, status=status.HTTP_400_BAD_REQUEST)
# Proceed with user creation
user_serializer = UserSerializer(data=request.data)
if user_serializer.is_valid():
user = user_serializer.save()
user.set_password(request.data['password'])
user.username = request.data['mobile_number']
user.first_name = request.data['first_name']
user.last_name = request.data['last_name']
user.save()
customer_data = {
'user': user.id,
'mobile_number': request.data['mobile_number'], # Ensure mobile number is provided
'semat': request.data['semat'],
}
customer_serializer = CustomerSerializer(data=customer_data)
if customer_serializer.is_valid():
customer_serializer.save()
token = Token.objects.create(user=user)
# return Response({'token': token.key, 'customer': customer_serializer.data, 'user': user_serializer.data}, status=status.HTTP_201_CREATED)
# Make a mutable copy of the request data
data = request.data.copy()
data['adminUser'] = request.user.id # Automatically assign the authenticated user as admin
data['user'] = user.id # Automatically assign the authenticated user as admin
# Pass the request object to the serializer context
serializer = TeamMemberSerializer(data=data, context={'request': request})
if serializer.is_valid():
# Save the team member using the validated data
team_member = serializer.save() # This automatically saves the team member
# Return the response with the team member data
return Response({
"message": "Team member added successfully.",
"team_member": serializer.data # This gives you the serialized data of the saved team member
}, status=status.HTTP_201_CREATED)
else:
# If validation fails, return the errors
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
# If customer data is invalid, delete the created user
user.delete()
return Response(customer_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

View File

@ -3,7 +3,7 @@
POST http://127.0.0.1:8000/signup
Content-Type: application/json
{ "username": "adam3", "password": "Pass1234!", "email": "adam2@mail.com" , "mobile_number":"09140086509" }
{ "username": "09140086509", "password": "12345678", "email": "adam2@mail.com" , "mobile_number":"09140086509" }
###
@ -85,3 +85,12 @@ Content-Type: application/json
Authorization: token d3f1b03996140c8f7561d67221953ff704b482cb
{ "verification_sms_code": "807806" }
###
POST http://127.0.0.1:8000/add_teamMember
Content-Type: application/json
Authorization: token 8dcae0063521ca707a9d0ab6ce3d4794a90064ca
{ "mobile_number": "09140086608", "first_name":"mahdi", "last_name":"arabi", "semat":"modir", "password": "12345678", "isAdmin":"true" }