From 43ccf7fb34296d9efe0dfe45af76206c033fd1d8 Mon Sep 17 00:00:00 2001 From: "afanasyev.aa" Date: Sun, 6 Apr 2025 04:59:28 +0900 Subject: [PATCH] unfinished logging --- api/__pycache__/models.cpython-313.pyc | Bin 3029 -> 3198 bytes api/__pycache__/urls.cpython-313.pyc | Bin 1604 -> 1624 bytes api/__pycache__/views.cpython-313.pyc | Bin 11842 -> 13190 bytes api/migrations/0001_initial.py | 63 +++++++++++++------ api/models.py | 9 ++- api/urls.py | 2 +- api/views.py | 48 +++++++++++--- testapi/__pycache__/settings.cpython-311.pyc | Bin 4112 -> 3840 bytes testapi/__pycache__/settings.cpython-313.pyc | Bin 4054 -> 3799 bytes testapi/settings.py | 45 ++++++++----- 10 files changed, 117 insertions(+), 50 deletions(-) diff --git a/api/__pycache__/models.cpython-313.pyc b/api/__pycache__/models.cpython-313.pyc index e6a5112c61178ece214380cbe40581904bb39477..2531206073154fc073ff2478cd24b9fec957daca 100644 GIT binary patch delta 1192 zcmah{&ubGw6yC|s?q+wBG~2XEsA;jaHLlgFM2p2AP@}cBRTO1d2bTGlaZg{ zuqME$p8YZ1ELS2)@~x8Y+Gz(mb#(=3%x2Y+trb413y1W*27i<(X2kif_tP08gJ= zW!*7T^wd&uvS2%Q*=9QGv^eiL{3+?=kHyv|wgEY5%E=Wkun^2om@)od>T2?oY`>N5 zKYYYfR}JGWfmYr~2M)&|(2uU!(u~VQ9k3MlA^`XpjlYeyzmB%w?S2}6-uA5R)tUUO z^TnlT>C!QNiH^&@s|o&zehgzyldu*)4Sy+h4zVtrQ-sX`9>u5jw6*)OZK!QWSg)cC z3J5WNR35CImEkw!YZ2e6Y7(Te0hZ#smA%<57;GYJMd$|b)aH}u$I&uj_W#AOnOV_$pH z2r{*Y^}X~9@zY_ati8P#+z*@Q9s3|V4g!JCodozU5<)%*`m&H(7J8P2%nBuBm|Wez ZBH(`|D3b%%CNBL8F4(vkW$B_j4UG#I#(QoViAfXh;+u27bI*5P^E>{zJ8~8dn-V|u zfgc5?)*^B8vvzqX6qnMHtt2H|U6o;7kJS!oSQDhiN&SM<1!-`SUXX?$O-=@VvP}>1 zYuLY1)hrMz0!fmNZ(x4^Xy?Y+f&}m7Vc6AsW46j@L9=vEd0cT=UExnw;8$Q!krpiz zPRJx2C@ILu(`^{d5b#YU2@6IKeR-F42^#i|gnZ)5js;~~ogmCyRhFYLLt~mP+u8(y z(LgeClLz2oVc!cMDeaHg25T!&%k<18=H!bT)nd6+*ZIShS!VDL^eTOwo>JOzT~B@H z=1R|5h|`N!J3LYnF?IP_lV)&&u%NS;N9|nIaou9osbe&@51;h$Y>Ngxn%&H?*`nj-`DAiiPRo3w zm=B>7=8PN7e4`)sjXiQ52XQ`MkMgX}mQ!WBmdvhjhZkaw%WKK63F$tR>4A(nbge}x zY#7}l)m4n86~7Cpn&Xp$$m!d;UALUe|7Sk8PzeF6tGp50QG=DR*beemkVWBDaAZ$? zSmw(Se`Ry0VziMSC diff --git a/api/__pycache__/urls.cpython-313.pyc b/api/__pycache__/urls.cpython-313.pyc index 597ee426520803deedfd40d19b3eafcfe8584f28..e6fab15688463dffb8ecac3e824f4aac68d865e8 100644 GIT binary patch delta 259 zcmX@YbAyNXGcPX}0}$AzeoU8}$h(A@Glpg2J9$a2U=B;>7)B+AVD1>cU>-P+cj6mG zUOqUNKZXscnpXfWAQ;0A6yO$u3kXjxU{o|0f%8RUxPrytJn0;kLcIfLtR7MJ8KF3VY6a16T05;k#`9*TMWy@ck+^)!5o&%F^ozK!CWzX!Q5~j&%`&1 zyu5HOUkn>iH7`G0Kp=)4D8MZU7Z93Uz^G_04Cjl)a0QFPd15i#!Qyb9L<~=`B%CJ| z!vQi|8ZICc!wC|Q1qtZ$6bYuwY07U_U{Yt?9L4;Mk&$n*Bdd)_hwKFjt?Lp-mn4iX ROPE}+_PNO7J9!f8F#z^%HXi^0 diff --git a/api/__pycache__/views.cpython-313.pyc b/api/__pycache__/views.cpython-313.pyc index 0c475326503a106fae1a2da9b4564e884ad03bb0..f3d50be3abbefae436f0fbfbcf77d196a5d9740f 100644 GIT binary patch delta 4486 zcmb7HeN0=|6@S;?!N%tE88DC+^J%`n1Nk7KAxT3bpg1fEkUEb20H?;L_nGEXHSM;D zEtSG_J0;q*Xq_fC?4!-fq(y6|soR=OohI3(o9R>1ZfiAle=RI@e^uSixi1FVQf;&3 z-@Esmd(ZuybI(2RzF&=9o~VA1nVBKL&va&G;zYS1ypNsq&-}3QU|Ro^>N*nl3SRMW zV_y?(>T9OWeJ!*_5l!n+>oq0qqb3#)#9HH`JM{NXVsi(nNEciB@~VL0%5h?6U0)F|ZX|9T#J&U@@%R1gV|$_LuMnnh3hXh5NFr>nxqwB)T(-B$O7yJ9?BuiY~!%L8dk-hzf%x~b?lZak7Z`%8}(j87h&HqS5(;qVKh@4BM4rj*VIJ3X0N47 zS1ycVK>2Sdi#=({W%ex5xTT8><+2rX?#>La)obh00cJMnBBs&&^ypzzI?W|vT{4u6~G^-?@)34eTNcC_y6q9|SplSr?*ljI8*=prrdzjBg!^p{JN%bT@#%L zEBjlv82^_^uoZmQ@S@`dM@s5QN*%ZB5>iJ(I+&9BlTv?58ca%qcXM6Wk0+`I62*gw z6JyETlL_0&Rg>VXNQrexu`VUHCdJmc06 z&6qQ{V~stCIGXn+R`PTHm!g?|Qc1wk>(~&mBzU zRU~bdn~Rn!Tju+dwz3aIDJ51X#p;yU_?Fn16nEUJ0+_SjbvWNHsJl6OJC-cyO%)tU z793h~^d&5PTGfHA9~b&zM@BICqX=UNClRs{cxA&t)5j4oS2k3)Q`kko%~o*2r>a|l z@i5UwpW@~1t(*}OWS`{!@yLRypH9MX8Ui><&tNkQuwd3w2Gfb+eL%~u^;CHZ2N9k@ z3hb@`slZ0^y2vDZKF?Rj>n?Ka_gFXe$%rO3$Jo|J5fW@tn&1JSeO(*HoPfHfB8TRDG?BpWE4C4($cSm4A{s#-!3CFYMnb;5VFgyH^o zVGsE#>nU;{-{4Zle+xHK<3WG6Db@;B zSkl|NmLjU@iL-t>p=bq#q7_~l^l&p!Em0bjsqgf8kAV)c`I0g#e=Q>uwVX-Y3Rq{M zja+5#m)s!R7oRQtJ+baW3*89gY(#2{zlhD72nz^50Dy8?h;6KA^Z){{ga@&uN5Jw! z42+<)|f z{h%C^_IZa6z$^a=IpWc&X3aTx=>=saKtt1b0c0OmoG{V}n8prO*0=F8*ap3gG*t@( z*%wggIQ=!KUPpB`z^ni-o2+7Xv(hc%>Z)OIzg-$S2byFrD0gq0L%^kL{x;@^6!;ImmKd7jN)6w90Z7YgFOt&IP0Fcd` zCqElJuy;^}afWQ(n9OQM7`gCo4f-ai@UJ`v0NibYE$ixzukVo^ z{R1f9!vT2gXNCI~!IsOuSJS~W#dDCoTk{5dNqoQdD)}*MtLxWdAO_F)BNNevDY%z~ zWvD)K1K$8Q*iZ|pti<5b=bw@xnol$YJeLW%M zJ)tuxblwx{*l_*fj`xI-q%d+%XuKyh|HYiYWOmLP{%JCkA+jnKlG^LrR|R;icDl%6 za^1Nq;B&Q`y;&cKujB|i$93cU*+kv0B-#BA*)rEYSG7cP-XXd3$LIT&$kr8|p5#5y z3pxoQ7oq#U31llaoNJmtcXKRBb}SPc&hD72ULv{g5a)H>5^-&`l1cWgSt-UA7#$FF mnb_QUKLgY&Qrh6jB-y#q+Bz2_*-O^Ua9X=oOeo|p{{H~B(-*@4 delta 3290 zcmb7GdrVu`8NbKA*EW9eumKy)!x%z+d71NPN~?9*QMF2IQ?*i~W}3FFY+W{KOEfJ}rTzmW8`)i^J^$&XNm)WRsg8 zj&0hN{k!My8)yB%R*ah>33jE@!(t{|!9LDc z0$&CE%r@V_`D)+;z^AtP{hY4>J_!8W7T@2+`C8!Xa(3>gn2bJ%C1Pl5J5(GcK) zs0?^;I!|s`e%)*~Eq^SH5K_mETgRj}u*lDDSl{#4Lu<;kX+6Gd@JE9mpIg3QJ4Q+f zlK6~>9h>cdu>3*ZmrbOe4LaLv4}y$710ef#X^tk-8tp-<7a<>^lfCU6BO&%rr{B_w zL^G>)^^$`u=Gxah0EAvNN0mf!N=s(aF{-H9l%^Af9srSQ1qc`q4YOOWI*W|-DEr8D zrb^12CJzG5>w%tM1bS{xtObs(I4d7Gi&osV_ndWXCSR|p8R!&#-dTLO%Y4V#7d+f< zzS}~ebGKbO+{Gpe4kdN>oI+=ls*0OWrQ)ips5F9FmBeDI7T1zfvACwuZ17I~aw{G1@WO%|I?QIXxQ@a~hgB0gds5u=u< zwM$G(V+F<{f-qLJ)f$mNYU?sZ+?clR%{-|S>r-sqV7&8DMeEf;B_F?bT*Zei7w8@(+jd)cfOca=t68RPUEvG#ay6h z0zHB&TTUlannI})JC3vQR2CwZ0yk0%j&UJ$0>~CRgzaGj)QNr(Ar4TjJ9gAlRh+k# zeKi?)6;F7@)3@#!TJ;QlkXiFg+^-1Xue$bOp5P5X6eO?x zl4HXu6#DM@n%*6|sjd13)_q4-eMi;`j;`2_8i|GZI1CnzpnfM2oxx+XL=+{vVOAQ<8f71rRgwuX?N|O6akPq{0cFwG2gBcjZ!e5T*8=qoj*!{Hy{I!^GEZ$uyL<^pv7v?GIoq{!-aTRMu1#9L=%R z{=Z^@yK?(3VQaT|ETRD647*lUXBfH2R;uR7!t%4#-y!+BQ;lm%DwWifSTeyr2@LGR z!_1RNx4bYPr_-vDM>9xcM(bv{W^`MICKMW*T#!XN#Ar>eg%{*3`zDl{3+ztKRkC+E z5&V$2_T$7Z07&Cr)?L@W_&PFgAY4Uw6J-Uo4BJ>BXdePE8lS@!-iQ=W3dN&OeF$91 zqtMbtEjg=DFOsMoJq934IVI++$bJEVR}M+Y->fRe6%t{e)YXueS>>KvlR3_J?&^H5 zBhM>-B#Lp>QwTf^5p3-ihL=!)u)q%1HyUAhiDl}i$Qx`iRL=fdf1q_3#85*sbT+PS zCkD>rJ}-zW{F1~gsbyNx-eRYos%Y8Pmwp9CUf*5kN?fE0fZdXOeVfM^x)6GP!Okk$ zOeSGCZ#U(!)KUbDm@2aiat*VGoQ4(efE6cQ_UC3YeX~dSeR&Nmnh*1;vy3yZ{h7*n1383i?3~=5$7f)d{ZT$;(=7=_izid;P($-x z^e4qHp4`oK8*CPvQt4^>LlAuz#q|J7!h-@od#fQR;)=_^ZU~V=)LysE!8ge~21e*Q?L_feWmjOUWN5L!Im%G0<{f*R>)S9DqY2bbV6Px?V@7c4> zZCrJBx%n!2pUEwL%a36W?P5n;0;Gq%&=TYsmQ!SP2kex|YQ|Q#Vf0=2tK9%_vpU@D zr!7zOAj`e%ZH fHw1idRI!o0QzehwW>WmfnNNBj2PJaIxRU<`_S^27 diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py index 8c138ed..26e6db6 100644 --- a/api/migrations/0001_initial.py +++ b/api/migrations/0001_initial.py @@ -1,9 +1,12 @@ -# Generated by Django 4.2.20 on 2025-04-05 15:24 +# Generated by Django 5.1.7 on 2025-04-05 16:49 +import django.contrib.auth.models +import django.contrib.auth.validators +import django.db.models.deletion +import django.utils.timezone +import uuid from django.conf import settings from django.db import migrations, models -import django.db.models.deletion -import uuid class Migration(migrations.Migration): @@ -11,20 +14,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('auth', '0012_alter_user_first_name_max_length'), ] operations = [ - migrations.CreateModel( - name='Prediction', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('result', models.JSONField()), - ('deleted_at', models.DateTimeField(blank=True, null=True)), - ], - ), migrations.CreateModel( name='Satellite', fields=[ @@ -33,18 +26,41 @@ class Migration(migrations.Migration): ], ), migrations.CreateModel( - name='User', + name='Prediction', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('result', models.JSONField()), + ('deleted_at', models.DateTimeField(blank=True, null=True)), + ('satellite', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='predictions', to='api.satellite')), ], ), migrations.CreateModel( - name='UserPrediction', + name='User', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField()), - ('prediction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.prediction')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('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')), + ('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')), + ('satellites', models.ManyToManyField(related_name='users', to='api.satellite')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), ], ), migrations.CreateModel( @@ -60,4 +76,13 @@ class Migration(migrations.Migration): ('satellite', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='telemetry', to='api.satellite')), ], ), + migrations.CreateModel( + name='UserPrediction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField()), + ('prediction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.prediction')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), ] diff --git a/api/models.py b/api/models.py index 3bb0c21..bb29c77 100644 --- a/api/models.py +++ b/api/models.py @@ -1,10 +1,14 @@ import uuid from django.db import models from django.contrib.auth import get_user_model -class User(models.Model): - id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) +from django.contrib.auth.models import AbstractUser + +class User(AbstractUser): + satellites = models.ManyToManyField("Satellite", related_name="users") + class Prediction(models.Model): + satellite = models.ForeignKey('Satellite', on_delete=models.CASCADE, related_name='predictions', null=True) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -12,7 +16,6 @@ class Prediction(models.Model): deleted_at = models.DateTimeField(null=True, blank=True) - class UserPrediction(models.Model): user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) prediction = models.ForeignKey("Prediction", on_delete=models.CASCADE) diff --git a/api/urls.py b/api/urls.py index 74dfdab..32a2a2b 100644 --- a/api/urls.py +++ b/api/urls.py @@ -12,7 +12,7 @@ from rest_framework.authtoken.views import obtain_auth_token from .views import TelemetryListCreateView urlpatterns = [ path('predictions', PredictionCreateView.as_view(), name='create_prediction'), - path('predictions', PredictionListView.as_view(), name='get_predictions'), + path('predictions/list/', PredictionListView.as_view(), name='get_predictions'), path('token', obtain_auth_token, name = 'get_token'), path("history", PredictionHistoryListView.as_view(), name='view_history_list'), path("history//", PredictionHistoryDetailView.as_view(), name='view_history_detail'), diff --git a/api/views.py b/api/views.py index a0e4d91..8c1469c 100644 --- a/api/views.py +++ b/api/views.py @@ -20,6 +20,9 @@ from rest_framework.authentication import SessionAuthentication, BasicAuthentica from django.contrib.auth import authenticate, login, logout import json from django.middleware.csrf import get_token +from rest_framework.decorators import api_view, permission_classes, authentication_classes +from drf_spectacular.utils import extend_schema +from django.utils.dateparse import parse_datetime User = get_user_model() @@ -50,7 +53,6 @@ class PredictionCreateView(APIView): try: prediction_result = TawhiriClient.get_prediction(validated_data) - print(prediction_result) except requests.RequestException as e: print("Tawhiri error:", str(e), e.response.text if e.response else "no response") return Response({"error": f"Tawhiri error: {str(e)}"}, status=status.HTTP_502_BAD_GATEWAY) @@ -65,19 +67,35 @@ class PredictionCreateView(APIView): class PredictionListView(APIView): + permission_classes = [IsAuthenticated] + def get(self, request): - user_id = request.query_params.get('user_id') + user = request.user + satellite_id = request.query_params.get('satellite_id') created_from = request.query_params.get('created_from') created_till = request.query_params.get('created_till') - predictions = Prediction.objects.filter( - id__in=UserPrediction.objects.filter(user_id=user_id).values_list('prediction_id'), - created_at__gte=created_from, - created_at__lte=created_till, - deleted_at__isnull=True - ) - return Response(PredictionSerializer(predictions, many=True).data) + # Проверка доступа к спутнику + if satellite_id and not user.satellites.filter(id=satellite_id).exists(): + return Response({'detail': 'Access to this satellite is forbidden.'}, status=403) + filters = { + 'id__in': UserPrediction.objects.filter(user=user).values_list('prediction_id', flat=True), + 'deleted_at__isnull': True + } + print(filters) + print(Prediction.objects.filter(**filters)) + if created_from: + filters['created_at__gte'] = parse_datetime(created_from) + if created_till: + filters['created_at__lte'] = parse_datetime(created_till) + if satellite_id: + filters['satellite_id'] = satellite_id + + predictions = Prediction.objects.filter(**filters) + return Response(PredictionSerializer(predictions, many=True).data) + + class PredictionHistoryListView(generics.ListAPIView): permission_classes = [permissions.IsAuthenticated] @@ -172,12 +190,20 @@ class WhoAmIView(APIView): return JsonResponse({'username': request.user.username}) +@extend_schema(methods=["GET"], description="Get CSRF token") +@api_view(["GET"]) +@permission_classes([AllowAny]) def get_csrf(request): response = JsonResponse({'detail': 'CSRF cookie set'}) response['X-CSRFToken'] = get_token(request) return response +@extend_schema(methods=["POST"], description="Login user") +@csrf_exempt +@api_view(["POST"]) +@authentication_classes([]) +@permission_classes([AllowAny]) def login_view(request): data = json.loads(request.body) username = data.get('username') @@ -187,7 +213,6 @@ def login_view(request): return JsonResponse({'detail': 'Please provide username and password.'}, status=400) user = authenticate(username=username, password=password) - if user is None: return JsonResponse({'detail': 'Invalid credentials.'}, status=400) @@ -195,6 +220,9 @@ def login_view(request): return JsonResponse({'detail': 'Successfully logged in.'}) +@extend_schema(methods=["POST"], description="Logout user") +@api_view(["POST"]) +@permission_classes([AllowAny]) def logout_view(request): if not request.user.is_authenticated: return JsonResponse({'detail': 'You\'re not logged in.'}, status=400) diff --git a/testapi/__pycache__/settings.cpython-311.pyc b/testapi/__pycache__/settings.cpython-311.pyc index 92a452d96d47806876ac0b18292d04805289ec32..db428a7ce5818d85f18ce40f39df92099b885d93 100644 GIT binary patch delta 505 zcmbQB&>*L=oR^o20SG?%e@uTV%)sy%#DM`0DC2V&<3x>p^{Jdi+$lmS!l~>jB30ZB z3@M^>m@*loMDjqQVkzP&5-E}?QYq3YGIQ8K;wiEza+!=kQXWhyfJwzn#&nh_(G;a9 zu@vPf@f6l52_TkCQHhdDQH_#LQA<%z(MZuuXH3xoVr?MS0b<=b>`}5ZDSA<|Kr9E; zAP>X}DIDpHQHm+d!3>)Eo0FIpverwbWF_XM=j){;=_Ms5XQ$?+6zdfi=46(n8dq@v z1)*$Brdw>Te(s)ruD4kH9DQA@WU=Tg$S*EQFG>Y!xy6=Jl$KbKd5Z%kc8kT($k_B2 zXHI@{VonB7;Vl+Z6JsMDO|~LlV4xN80g1`o9I|X6MwQ3p1FRyGdpSimU*p)%#4QUH zyT$C2SfQ!3c>y;ojMLbU}hC$Yw&FF{2;)$#H$xM3*r!Fsue*2p~d_Sc*77J@qj2pmd5viX=fz=z645q)FBzlOhY!Q;+abirgHw zOvWg&6!{c|OhzE72qu-lq;e)>I!lyzib|A3ifWW(3Tu=U5KE`1MaiV7N6DsWq-dsS zrD&%!rsx2%E)eShvHl$PD7h4aD0v`O0IF96Vx<(0bjB#<6y{(CO~b^^&5R3JCr7i( zXR^CE#rrw>y53?-DN0K$$h-v-2n}`(y2VkDUtE%2lv;d?8z>au7#tk#ALMe2#n8yu z6s*d_KRDzTXHI@{VonB7DOfDPKPcoDi>ZmRktW+MHdjA)Pe0dNEFcReuVa^Gl-PWR z{S6bh5-=!lG5aJ|XsT>J%*D#c%buE7mRXdacZ)eawPf>gZbe2eAD|jWATHLP{E6p% zJs$%r-wh$d8v;U8xTf<>;+s*qLgS)<@f87MWFf7K0;X34OmB#YP4SxUH_2~-?FO}r zB9>P~ERj`dUlcIAB4CCrq;^rj@QQ%p2VQmowhs&-f|-+-se$u@0s|-i1%ar^)_ez9 IynxOD0N$RUI{*Lx diff --git a/testapi/__pycache__/settings.cpython-313.pyc b/testapi/__pycache__/settings.cpython-313.pyc index 6e62f8dea21dbb4885a9c6e53e7c23aed54358d2..41aa746d80c9f64bb0715b1a7a7e63a8bc26daa6 100644 GIT binary patch delta 567 zcmXw#yKmD_6vq9$v7I)3eD|KKqx&=cD_K03Wr-qn=kd7v zEkaR$Ce8m6W^lewpA^5p+7^qm!0=KOgdwu+0cB;va~e~ov9jeQX%yxm1`7~}MM!99 zl0yY1r$%XEpubCAPP$m4n7ag1mIF5x&_#*1(TC!hdDP~j>pl^7^2muOfa z(lmsVP{JvqG#SYdWkD#>IM-#>@@T+(;IGBoPmRNFUu*AbyT;zL&SBfs%%k4Hai{u1 zBH@fx#zA`XUZbfyTyt$xw}L{ZhT3@F7#ujlpl=>`amRGH)k?MQh`s)v(R)HdhpX4B z6%}Eb{0R0Fv)&6y+CTa%=(H%1VXb9$u=Q7bYyFmL)*A^J6q$AFtFBobbqG>`oo>gt#y6FT9v;@cgd49k@?ZOkWX)4_$W?16GC>hVk?PvFMlXY zW1dwcm*qp~b;Au(V%Uz>$(gOB>{!ZH(zX&G%bv*d)?Qmika1oV#K-(eZ tEOCplc*7QMx;$Gzu8$JyF3aYpRCZY=i^kbVm>K%rW$QGMaw7pCsBx;m1Nzk2GpA9dh^GaB=2`j3i91l#v1g~%-ff_I8&43bx(aZ&q8G3$x184;*UbuSU}3BE zptkjxSRJlf(KoP5yO3W_a+oWYZ>*Jz*fm^We&R!Ppm)F*X)`6fFn)xMG+XO{YkX8HWxl2PiGjq>ZO`-#5q(zqwpS1yh-iN2B>NW8+? ztROLaf*qlRQ(u&OHp{p<+d~OvLatsWP4qTxo%UJ5l|$hQ5f>d%vspII*&-!m2^V#^ WYmPbyd%et_Y^&xwIp!*n>-+?b`>tmI diff --git a/testapi/settings.py b/testapi/settings.py index 2d38109..d8715c1 100644 --- a/testapi/settings.py +++ b/testapi/settings.py @@ -89,16 +89,24 @@ WSGI_APPLICATION = 'testapi.wsgi.application' # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.environ.get("DB_NAME", "drfapi"), - 'USER': os.environ.get("DB_USER", "postgres"), - 'PASSWORD': os.environ.get("DB_PASSWORD", "1235"), - 'HOST': os.environ.get("DB_HOST", "localhost"), - 'PORT': os.environ.get("DB_PORT", "5432"), +if DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'drfapi', # Your database name + 'USER': 'postgres', # Your PostgreSQL username + 'PASSWORD': '1235', # Your PostgreSQL password + 'HOST': 'localhost', # Or your DB server's IP + 'PORT': '5432', # Default PostgreSQL port + } } -} # Password validation # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators @@ -140,27 +148,30 @@ STATIC_URL = 'static/' # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +AUTH_USER_MODEL = 'api.User' -REST_FRAMEWORK = { - # ВАШИ НАСТРОЙКИ +REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 100, - 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', + + 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', + 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework.authentication.TokenAuthentication', + 'rest_framework.authentication.TokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', ], + 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', - #'rest_framework.permissions.AllowAny', + # 'rest_framework.permissions.AllowAny', ], + 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', ], - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework.authentication.SessionAuthentication', - ], } + CSRF_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_HTTPONLY = True