diff --git a/.idea/SOITA.iml b/.idea/SOITA.iml index 66ca8ca..19acda8 100644 --- a/.idea/SOITA.iml +++ b/.idea/SOITA.iml @@ -14,7 +14,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index be60604..2161090 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/answers/urls.py b/answers/urls.py index e9553b2..e6f4956 100644 --- a/answers/urls.py +++ b/answers/urls.py @@ -2,7 +2,7 @@ from rest_framework.routers import DefaultRouter from answers.views import AnswerModelViewSet -router = DefaultRouter() +router = DefaultRouter(trailing_slash=False) router.register("items", AnswerModelViewSet) urlpatterns = router.urls diff --git a/config/settings.py b/config/settings.py index 66b57e0..b6a07f7 100644 --- a/config/settings.py +++ b/config/settings.py @@ -46,6 +46,7 @@ INSTALLED_APPS = [ "django.contrib.gis", "rest_framework", "rest_framework_simplejwt", + "django_extensions", "users", "trials", @@ -100,10 +101,10 @@ DATABASES = { REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ( - # "rest_framework.permissions.IsAuthenticated", + "rest_framework.permissions.IsAuthenticated", ), "DEFAULT_AUTHENTICATION_CLASSES": ( - # "rest_framework_simplejwt.authentication.JWTAuthentication", + "rest_framework_simplejwt.authentication.JWTAuthentication", ), "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", "DEFAULT_FILTER_BACKENDS": ( diff --git a/requirements.txt b/requirements.txt index 5c552e3..12c912c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,36 +1,110 @@ +alabaster==0.7.12 appdirs==1.4.4 +appnope==0.1.2 +argon2-cffi==21.1.0 asgiref==3.4.1 attrs==21.2.0 +Babel==2.9.1 +backcall==0.2.0 +bleach==4.1.0 botocore==1.21.15 +certifi==2021.10.8 +cffi==1.15.0 +charset-normalizer==2.0.9 +debugpy==1.5.1 +decorator==5.1.0 +defusedxml==0.7.1 distlib==0.3.2 Django==3.2.9 django-cors-headers==3.10.0 django-debug-toolbar==3.2.2 +django-extensions==3.1.5 django-filter==21.1 +django-shell-plus==1.1.7 djangorestframework==3.12.4 djangorestframework-simplejwt==5.0.0 +docutils==0.17.1 drf-spectacular==0.21.0 +entrypoints==0.3 filelock==3.0.12 GDAL==3.3.3 git-remote-codecommit==1.15.1 +idna==3.3 +imagesize==1.3.0 +importlib-metadata==4.8.2 inflection==0.5.1 +ipykernel==6.6.0 +ipyparallel==8.0.0 +ipython==7.30.1 +ipython-genutils==0.2.0 +ipywidgets==7.6.5 +jedi==0.18.1 +Jinja2==3.0.3 jmespath==0.10.0 jsonschema==4.2.1 +jupyter-client==7.1.0 +jupyter-core==4.9.1 +jupyterlab-pygments==0.1.2 +jupyterlab-widgets==1.0.2 +Markdown==3.3.6 +MarkupSafe==2.0.1 +matplotlib-inline==0.1.3 +mistune==0.8.4 +nbclient==0.5.9 +nbconvert==6.3.0 +nbformat==5.1.3 +nest-asyncio==1.5.4 +nose==1.3.7 +notebook==6.4.6 numpy==1.21.4 +packaging==21.3 +pandocfilters==1.5.0 +parso==0.8.3 pbr==5.6.0 +pexpect==4.8.0 +pickleshare==0.7.5 Pillow==8.4.0 +prometheus-client==0.12.0 +prompt-toolkit==3.0.23 protobuf==3.17.3 +psutil==5.8.0 psycopg2-binary==2.9.2 +ptyprocess==0.7.0 +pycparser==2.21 +Pygments==2.10.0 PyJWT==2.3.0 +pyparsing==3.0.6 pyrsistent==0.18.0 python-dateutil==2.8.2 pytz==2021.3 PyYAML==6.0 +pyzmq==22.3.0 +qtconsole==5.2.1 +QtPy==1.11.3 +requests==2.26.0 +Send2Trash==1.8.0 six==1.16.0 +snowballstemmer==2.2.0 +Sphinx==4.3.1 +sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 sqlparse==0.4.2 stevedore==3.3.0 +terminado==0.12.1 +testpath==0.5.0 +tornado==6.1 +tqdm==4.62.3 +traitlets==5.1.1 uritemplate==4.1.1 urllib3==1.26.6 virtualenv==20.4.7 virtualenv-clone==0.5.4 virtualenvwrapper==4.8.4 +wcwidth==0.2.5 +webencodings==0.5.1 +widgetsnbextension==3.5.2 +zipp==3.6.0 diff --git a/trials/models.py b/trials/models.py index 0661aca..014c00c 100644 --- a/trials/models.py +++ b/trials/models.py @@ -3,7 +3,7 @@ from django.db import models class Test(models.Model): name = models.CharField(max_length=100) - passing_score = models.PositiveSmallIntegerField() + passing_score = models.PositiveSmallIntegerField(default=0) def get_score(self, answers): """ diff --git a/users/managers.py b/users/managers.py new file mode 100644 index 0000000..93aacfd --- /dev/null +++ b/users/managers.py @@ -0,0 +1,9 @@ +from django.contrib.auth.base_user import BaseUserManager + +from .querysets import UserQuerySet + + +class UserManager(BaseUserManager): + + def get_queryset(self): + return UserQuerySet(self.model, using=self._db) \ No newline at end of file diff --git a/users/models.py b/users/models.py index af77d96..886360f 100644 --- a/users/models.py +++ b/users/models.py @@ -1,6 +1,8 @@ from django.contrib.auth.base_user import AbstractBaseUser from django.db import models +from .managers import UserManager + class User(AbstractBaseUser): first_name = models.CharField(max_length=100) @@ -15,6 +17,8 @@ class User(AbstractBaseUser): USERNAME_FIELD = "email" + objects = UserManager() + class Meta: ordering = ("id", ) diff --git a/users/querysets.py b/users/querysets.py new file mode 100644 index 0000000..d4323d9 --- /dev/null +++ b/users/querysets.py @@ -0,0 +1,7 @@ +from django.db.models import QuerySet + + +class UserQuerySet(QuerySet): + + def activated(self, **kwargs): + return self.filter(is_activated=True) \ No newline at end of file diff --git a/users/serializers.py b/users/serializers.py index 89b380b..2209870 100644 --- a/users/serializers.py +++ b/users/serializers.py @@ -4,6 +4,16 @@ from users.models import User class UserSerializer(serializers.ModelSerializer): + + password = serializers.CharField( + write_only=True, + required=False, + min_length=8, + style={"input_type": "password"}, + ) + #todo + # avatar = serializers.ImageField(allow_empty_file=True, source="profile.avatar", read_only=True) + class Meta: model = User fields = ( diff --git a/users/urls.py b/users/urls.py index 35daf75..cf7ca52 100644 --- a/users/urls.py +++ b/users/urls.py @@ -6,11 +6,12 @@ from rest_framework_simplejwt.views import TokenObtainPairView from rest_framework_simplejwt.views import TokenRefreshView -router = DefaultRouter() +router = DefaultRouter(trailing_slash=False) router.register("items", UserModelViewSet) urlpatterns = [ - path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), - path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path("", include(router.urls)), + path('api/token', TokenObtainPairView.as_view(), name='token_obtain_pair'), + path('api/token/refresh', TokenRefreshView.as_view(), name='token_refresh'), ]