From b26af7b7085f3fda8b20c150b18f4554dd908ba7 Mon Sep 17 00:00:00 2001 From: tigdav <47061880+tigdav@users.noreply.github.com> Date: Sat, 13 Jun 2026 21:59:58 +0300 Subject: [PATCH 1/3] style: format code with ruff format --- backend/apps/gameplay/apps.py | 4 +- backend/apps/gameplay/models.py | 39 ++++---- backend/apps/gameplay/permissions.py | 5 +- backend/apps/gameplay/serializers.py | 20 ++-- .../apps/gameplay/tests/test_categories.py | 50 +++------- backend/apps/gameplay/tests/test_questions.py | 28 +++--- .../gameplay/tests/test_random_questions.py | 64 ++++--------- backend/apps/gameplay/tests/test_rules.py | 6 +- backend/apps/gameplay/urls.py | 8 +- backend/apps/gameplay/views.py | 20 ++-- backend/config/asgi.py | 2 +- backend/config/settings.py | 92 +++++++++---------- backend/config/urls.py | 4 +- backend/config/wsgi.py | 2 +- backend/manage.py | 5 +- 15 files changed, 137 insertions(+), 212 deletions(-) diff --git a/backend/apps/gameplay/apps.py b/backend/apps/gameplay/apps.py index 3099c18..6129b1c 100644 --- a/backend/apps/gameplay/apps.py +++ b/backend/apps/gameplay/apps.py @@ -2,5 +2,5 @@ class GameplayConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'apps.gameplay' + default_auto_field = "django.db.models.BigAutoField" + name = "apps.gameplay" diff --git a/backend/apps/gameplay/models.py b/backend/apps/gameplay/models.py index 18aa498..ed25c1e 100644 --- a/backend/apps/gameplay/models.py +++ b/backend/apps/gameplay/models.py @@ -2,52 +2,47 @@ class QuestionCategory(models.Model): - name = models.CharField(max_length=100, verbose_name='Category') - description = models.TextField(verbose_name='Short description') - is_adult = models.BooleanField(default=False, verbose_name='Adult category (18+)') + name = models.CharField(max_length=100, verbose_name="Category") + description = models.TextField(verbose_name="Short description") + is_adult = models.BooleanField(default=False, verbose_name="Adult category (18+)") - icon = models.FileField(upload_to='category_icons/', blank=True, null=True, verbose_name='Icon') + icon = models.FileField(upload_to="category_icons/", blank=True, null=True, verbose_name="Icon") def __str__(self): return self.name class Meta: - verbose_name = 'Question Category' - verbose_name_plural = 'Question Categories' + verbose_name = "Question Category" + verbose_name_plural = "Question Categories" class Question(models.Model): - text = models.TextField(verbose_name='Question text') + text = models.TextField(verbose_name="Question text") question_type = models.CharField( - max_length=100, - choices=[('truth', 'Truth'), ('dare', 'Dare')], - verbose_name='Question type' + max_length=100, choices=[("truth", "Truth"), ("dare", "Dare")], verbose_name="Question type" ) category = models.ForeignKey( - QuestionCategory, - on_delete=models.CASCADE, - related_name='questions', - verbose_name='Category' + QuestionCategory, on_delete=models.CASCADE, related_name="questions", verbose_name="Category" ) def __str__(self): return self.text class Meta: - verbose_name = 'Question' - verbose_name_plural = 'Questions' + verbose_name = "Question" + verbose_name_plural = "Questions" class Rule(models.Model): - text = models.TextField(verbose_name='Rule page content') - order = models.PositiveIntegerField(default=0, verbose_name='Display order') + text = models.TextField(verbose_name="Rule page content") + order = models.PositiveIntegerField(default=0, verbose_name="Display order") class Meta: - verbose_name = 'Rule Page' - verbose_name_plural = 'Rule Pages' - ordering = ['order'] + verbose_name = "Rule Page" + verbose_name_plural = "Rule Pages" + ordering = ["order"] def __str__(self): - return f'Page {self.order + 1}' + return f"Page {self.order + 1}" diff --git a/backend/apps/gameplay/permissions.py b/backend/apps/gameplay/permissions.py index a25edca..eca32bd 100644 --- a/backend/apps/gameplay/permissions.py +++ b/backend/apps/gameplay/permissions.py @@ -8,7 +8,4 @@ class IsAdminOrReadOnly(BasePermission): """ def has_permission(self, request, view): - return ( - request.method in SAFE_METHODS - or request.user and request.user.is_staff - ) + return request.method in SAFE_METHODS or request.user and request.user.is_staff diff --git a/backend/apps/gameplay/serializers.py b/backend/apps/gameplay/serializers.py index 89ecf44..7c1067e 100644 --- a/backend/apps/gameplay/serializers.py +++ b/backend/apps/gameplay/serializers.py @@ -5,32 +5,26 @@ class QuestionCategorySerializer(serializers.ModelSerializer): class Meta: model = QuestionCategory - fields = ['id', 'name', 'description', 'icon', 'is_adult'] + fields = ["id", "name", "description", "icon", "is_adult"] class QuestionSerializer(serializers.ModelSerializer): category_id = serializers.PrimaryKeyRelatedField( - source='category', - queryset=QuestionCategory.objects.all(), - required=True + source="category", queryset=QuestionCategory.objects.all(), required=True ) class Meta: model = Question - fields = ['id', 'text', 'question_type', 'category_id'] + fields = ["id", "text", "question_type", "category_id"] class QuestionRequestSerializer(serializers.Serializer): - question_type = serializers.ChoiceField(choices=['truth', 'dare']) - category_ids = serializers.ListField( - child=serializers.IntegerField(), allow_empty=False - ) - excluded_ids = serializers.ListField( - child=serializers.IntegerField(), required=False - ) + question_type = serializers.ChoiceField(choices=["truth", "dare"]) + category_ids = serializers.ListField(child=serializers.IntegerField(), allow_empty=False) + excluded_ids = serializers.ListField(child=serializers.IntegerField(), required=False) class RuleSerializer(serializers.ModelSerializer): class Meta: model = Rule - fields = ['text'] + fields = ["text"] diff --git a/backend/apps/gameplay/tests/test_categories.py b/backend/apps/gameplay/tests/test_categories.py index 71937fb..da1e0cc 100644 --- a/backend/apps/gameplay/tests/test_categories.py +++ b/backend/apps/gameplay/tests/test_categories.py @@ -6,17 +6,17 @@ @pytest.mark.django_db def test_create_category(): - User.objects.create_user(username='admin', password='adminpass', is_staff=True) + User.objects.create_user(username="admin", password="adminpass", is_staff=True) client = APIClient() - client.login(username='admin', password='adminpass') + client.login(username="admin", password="adminpass") data = { "name": "Childhood & Memories", "description": "Nostalgic stories, games, and funny moments from the past.", - "is_adult": False + "is_adult": False, } - response = client.post("/api/categories/", data, format='json') + response = client.post("/api/categories/", data, format="json") assert response.status_code == 201 @@ -36,11 +36,7 @@ def test_create_category(): @pytest.mark.django_db def test_anonymous_can_list_categories(): - QuestionCategory.objects.create( - name="Public Category", - description="Listed for anonymous clients.", - is_adult=False - ) + QuestionCategory.objects.create(name="Public Category", description="Listed for anonymous clients.", is_adult=False) client = APIClient() response = client.get("/api/categories/") @@ -51,11 +47,7 @@ def test_anonymous_can_list_categories(): @pytest.mark.django_db def test_anonymous_can_retrieve_category(): - category = QuestionCategory.objects.create( - name="Retrievable", - description="Detail view is public.", - is_adult=False - ) + category = QuestionCategory.objects.create(name="Retrievable", description="Detail view is public.", is_adult=False) client = APIClient() response = client.get(f"/api/categories/{category.id}/") @@ -66,16 +58,12 @@ def test_anonymous_can_retrieve_category(): @pytest.mark.django_db def test_non_admin_cannot_create_category(): - User.objects.create_user(username='alice', password='alicepass') + User.objects.create_user(username="alice", password="alicepass") client = APIClient() - client.login(username='alice', password='alicepass') + client.login(username="alice", password="alicepass") - data = { - "name": "Forbidden", - "description": "Should not be created by a non-admin user.", - "is_adult": False - } - response = client.post("/api/categories/", data, format='json') + data = {"name": "Forbidden", "description": "Should not be created by a non-admin user.", "is_adult": False} + response = client.post("/api/categories/", data, format="json") assert response.status_code == 403 assert QuestionCategory.objects.count() == 0 @@ -83,22 +71,14 @@ def test_non_admin_cannot_create_category(): @pytest.mark.django_db def test_admin_can_update_category(): - category = QuestionCategory.objects.create( - name="Original", - description="Before update.", - is_adult=False - ) + category = QuestionCategory.objects.create(name="Original", description="Before update.", is_adult=False) - User.objects.create_user(username='admin', password='adminpass', is_staff=True) + User.objects.create_user(username="admin", password="adminpass", is_staff=True) client = APIClient() - client.login(username='admin', password='adminpass') + client.login(username="admin", password="adminpass") - data = { - "name": "Updated", - "description": "After update.", - "is_adult": True - } - response = client.put(f"/api/categories/{category.id}/", data, format='json') + data = {"name": "Updated", "description": "After update.", "is_adult": True} + response = client.put(f"/api/categories/{category.id}/", data, format="json") assert response.status_code == 200 diff --git a/backend/apps/gameplay/tests/test_questions.py b/backend/apps/gameplay/tests/test_questions.py index c93122d..476ec68 100644 --- a/backend/apps/gameplay/tests/test_questions.py +++ b/backend/apps/gameplay/tests/test_questions.py @@ -10,21 +10,21 @@ def test_create_dare_question_in_strange_habits_category(): id=6, name="Unusual Habits", description="Quirky rituals, everyday oddities, and personal peculiarities.", - is_adult=False + is_adult=False, ) - User.objects.create_user(username='admin', password='adminpass', is_staff=True) + User.objects.create_user(username="admin", password="adminpass", is_staff=True) client = APIClient() - client.login(username='admin', password='adminpass') + client.login(username="admin", password="adminpass") data = { "text": "Do 10 squats while repeating your favorite weird word.", "question_type": "dare", - "category_id": category.id + "category_id": category.id, } - response = client.post("/api/questions/", data, format='json') + response = client.post("/api/questions/", data, format="json") assert response.status_code == 201 @@ -51,9 +51,9 @@ def test_anonymous_cannot_list_questions(): @pytest.mark.django_db def test_non_admin_cannot_list_questions(): - User.objects.create_user(username='alice', password='alicepass') + User.objects.create_user(username="alice", password="alicepass") client = APIClient() - client.login(username='alice', password='alicepass') + client.login(username="alice", password="alicepass") response = client.get("/api/questions/") @@ -63,19 +63,13 @@ def test_non_admin_cannot_list_questions(): @pytest.mark.django_db def test_admin_can_list_questions(): category = QuestionCategory.objects.create( - name="Listable", - description="Questions can be listed for admins.", - is_adult=False - ) - Question.objects.create( - text="Sample listed question?", - question_type="truth", - category=category + name="Listable", description="Questions can be listed for admins.", is_adult=False ) + Question.objects.create(text="Sample listed question?", question_type="truth", category=category) - User.objects.create_user(username='admin', password='adminpass', is_staff=True) + User.objects.create_user(username="admin", password="adminpass", is_staff=True) client = APIClient() - client.login(username='admin', password='adminpass') + client.login(username="admin", password="adminpass") response = client.get("/api/questions/") diff --git a/backend/apps/gameplay/tests/test_random_questions.py b/backend/apps/gameplay/tests/test_random_questions.py index e9c4584..52fc0bc 100644 --- a/backend/apps/gameplay/tests/test_random_questions.py +++ b/backend/apps/gameplay/tests/test_random_questions.py @@ -8,24 +8,18 @@ def test_random_questions_selection(): category = QuestionCategory.objects.create( name="Close Circle", description="Questions about friends, family, coworkers, and personal boundaries.", - is_adult=False + is_adult=False, ) for i in range(10): Question.objects.create( - text=f"Is it true that this is question number {i}?", - question_type="truth", - category=category + text=f"Is it true that this is question number {i}?", question_type="truth", category=category ) client = APIClient() - request_data = { - "question_type": "truth", - "category_ids": [category.id], - "excluded_ids": [] - } - response = client.post("/api/questions/random/", request_data, format='json') + request_data = {"question_type": "truth", "category_ids": [category.id], "excluded_ids": []} + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 200 @@ -42,16 +36,10 @@ def test_random_questions_selection(): @pytest.mark.django_db def test_random_questions_excludes_specified_ids(): category = QuestionCategory.objects.create( - name="Mixed", - description="Holds multiple truth questions.", - is_adult=False + name="Mixed", description="Holds multiple truth questions.", is_adult=False ) questions = [ - Question.objects.create( - text=f"Truth statement {i}?", - question_type="truth", - category=category - ) + Question.objects.create(text=f"Truth statement {i}?", question_type="truth", category=category) for i in range(8) ] excluded = [questions[0].id, questions[1].id, questions[2].id] @@ -62,7 +50,7 @@ def test_random_questions_excludes_specified_ids(): "category_ids": [category.id], "excluded_ids": excluded, } - response = client.post("/api/questions/random/", request_data, format='json') + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 200 returned_ids = [q["id"] for q in response.data] @@ -72,29 +60,19 @@ def test_random_questions_excludes_specified_ids(): @pytest.mark.django_db def test_random_questions_filters_by_type(): category = QuestionCategory.objects.create( - name="Mixed Types", - description="Has both truth and dare questions.", - is_adult=False + name="Mixed Types", description="Has both truth and dare questions.", is_adult=False ) for i in range(5): - Question.objects.create( - text=f"Truth {i}", - question_type="truth", - category=category - ) + Question.objects.create(text=f"Truth {i}", question_type="truth", category=category) for i in range(5): - Question.objects.create( - text=f"Dare {i}", - question_type="dare", - category=category - ) + Question.objects.create(text=f"Dare {i}", question_type="dare", category=category) client = APIClient() request_data = { "question_type": "dare", "category_ids": [category.id], } - response = client.post("/api/questions/random/", request_data, format='json') + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 200 assert len(response.data) > 0 @@ -105,22 +83,16 @@ def test_random_questions_filters_by_type(): @pytest.mark.django_db def test_random_questions_returns_empty_when_no_match(): category = QuestionCategory.objects.create( - name="Truth Only", - description="Only truth questions exist here.", - is_adult=False - ) - Question.objects.create( - text="Only truth here.", - question_type="truth", - category=category + name="Truth Only", description="Only truth questions exist here.", is_adult=False ) + Question.objects.create(text="Only truth here.", question_type="truth", category=category) client = APIClient() request_data = { "question_type": "dare", "category_ids": [category.id], } - response = client.post("/api/questions/random/", request_data, format='json') + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 200 assert response.data == [] @@ -129,9 +101,7 @@ def test_random_questions_returns_empty_when_no_match(): @pytest.mark.django_db def test_random_questions_invalid_type_returns_400(): category = QuestionCategory.objects.create( - name="Validation", - description="Used for validation testing.", - is_adult=False + name="Validation", description="Used for validation testing.", is_adult=False ) client = APIClient() @@ -139,7 +109,7 @@ def test_random_questions_invalid_type_returns_400(): "question_type": "invalid", "category_ids": [category.id], } - response = client.post("/api/questions/random/", request_data, format='json') + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 400 assert "question_type" in response.data @@ -152,7 +122,7 @@ def test_random_questions_empty_categories_returns_400(): "question_type": "truth", "category_ids": [], } - response = client.post("/api/questions/random/", request_data, format='json') + response = client.post("/api/questions/random/", request_data, format="json") assert response.status_code == 400 assert "category_ids" in response.data diff --git a/backend/apps/gameplay/tests/test_rules.py b/backend/apps/gameplay/tests/test_rules.py index 7fdb975..5fe3f8a 100644 --- a/backend/apps/gameplay/tests/test_rules.py +++ b/backend/apps/gameplay/tests/test_rules.py @@ -45,10 +45,10 @@ def test_rules_listed_in_order_field(): @pytest.mark.django_db def test_rules_endpoint_does_not_allow_write(): - User.objects.create_user(username='admin', password='adminpass', is_staff=True) + User.objects.create_user(username="admin", password="adminpass", is_staff=True) client = APIClient() - client.login(username='admin', password='adminpass') + client.login(username="admin", password="adminpass") - response = client.post("/api/rules/", {"text": "Should not work"}, format='json') + response = client.post("/api/rules/", {"text": "Should not work"}, format="json") assert response.status_code == 405 diff --git a/backend/apps/gameplay/urls.py b/backend/apps/gameplay/urls.py index 0b0ae70..a4b2a3c 100644 --- a/backend/apps/gameplay/urls.py +++ b/backend/apps/gameplay/urls.py @@ -3,10 +3,10 @@ from .views import QuestionViewSet, QuestionCategoryViewSet, RuleViewSet router = DefaultRouter() -router.register(r'questions', QuestionViewSet) -router.register(r'categories', QuestionCategoryViewSet) -router.register(r'rules', RuleViewSet, basename='rules') +router.register(r"questions", QuestionViewSet) +router.register(r"categories", QuestionCategoryViewSet) +router.register(r"rules", RuleViewSet, basename="rules") urlpatterns = [ - path('', include(router.urls)), + path("", include(router.urls)), ] diff --git a/backend/apps/gameplay/views.py b/backend/apps/gameplay/views.py index 1a77818..e1772fe 100644 --- a/backend/apps/gameplay/views.py +++ b/backend/apps/gameplay/views.py @@ -13,24 +13,18 @@ class QuestionViewSet(viewsets.ModelViewSet): serializer_class = QuestionSerializer permission_classes = [IsAdminUser] - @action( - detail=False, - methods=['post'], - url_path='random', - permission_classes=[AllowAny] - ) + @action(detail=False, methods=["post"], url_path="random", permission_classes=[AllowAny]) def get_random_questions(self, request): req_serializer = QuestionRequestSerializer(data=request.data) req_serializer.is_valid(raise_exception=True) - question_type = req_serializer.validated_data['question_type'] - category_ids = req_serializer.validated_data['category_ids'] - excluded_ids = req_serializer.validated_data.get('excluded_ids', []) + question_type = req_serializer.validated_data["question_type"] + category_ids = req_serializer.validated_data["category_ids"] + excluded_ids = req_serializer.validated_data.get("excluded_ids", []) - queryset = Question.objects.filter( - question_type=question_type, - category__id__in=category_ids - ).exclude(id__in=excluded_ids) + queryset = Question.objects.filter(question_type=question_type, category__id__in=category_ids).exclude( + id__in=excluded_ids + ) random_questions = queryset.order_by(Random())[:5] diff --git a/backend/config/asgi.py b/backend/config/asgi.py index 407d660..6616808 100644 --- a/backend/config/asgi.py +++ b/backend/config/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") application = get_asgi_application() diff --git a/backend/config/settings.py b/backend/config/settings.py index 705db48..162baad 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -25,69 +25,69 @@ # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.getenv('SECRET_KEY') +SECRET_KEY = os.getenv("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = os.getenv('DEBUG', 'False') == 'True' +DEBUG = os.getenv("DEBUG", "False") == "True" -ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '').split(',') +ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",") # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'rest_framework', - 'apps.gameplay', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "rest_framework", + "apps.gameplay", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'config.urls' +ROOT_URLCONF = "config.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'config.wsgi.application' +WSGI_APPLICATION = "config.wsgi.application" # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.getenv('DB_NAME'), - 'USER': os.getenv('DB_USER'), - 'PASSWORD': os.getenv('DB_PASSWORD'), - 'HOST': os.getenv('DB_HOST', 'localhost'), - 'PORT': os.getenv('DB_PORT', '5432'), + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.getenv("DB_NAME"), + "USER": os.getenv("DB_USER"), + "PASSWORD": os.getenv("DB_PASSWORD"), + "HOST": os.getenv("DB_HOST", "localhost"), + "PORT": os.getenv("DB_PORT", "5432"), } } @@ -97,16 +97,16 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -114,9 +114,9 @@ # Internationalization # https://docs.djangoproject.com/en/5.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -126,13 +126,13 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.1/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = "static/" # Media files (uploaded by users) -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DIR, "media") # Default primary key field type # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" diff --git a/backend/config/urls.py b/backend/config/urls.py index ae8401d..f71553d 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -4,8 +4,8 @@ from django.conf.urls.static import static urlpatterns = [ - path('admin/', admin.site.urls), - path('api/', include('apps.gameplay.urls')), + path("admin/", admin.site.urls), + path("api/", include("apps.gameplay.urls")), ] if settings.DEBUG: diff --git a/backend/config/wsgi.py b/backend/config/wsgi.py index 140be65..1a270ec 100644 --- a/backend/config/wsgi.py +++ b/backend/config/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") application = get_wsgi_application() diff --git a/backend/manage.py b/backend/manage.py index 8e7ac79..aabb818 100644 --- a/backend/manage.py +++ b/backend/manage.py @@ -1,12 +1,13 @@ #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" + import os import sys def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +19,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() From 5f2edefbf751744c8720a796594075b7ecae153b Mon Sep 17 00:00:00 2001 From: tigdav <47061880+tigdav@users.noreply.github.com> Date: Sat, 13 Jun 2026 21:59:58 +0300 Subject: [PATCH 2/3] ci: add ruff format check --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ca1d84..57ed941 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,10 @@ jobs: working-directory: backend run: ruff check . + - name: Check formatting with Ruff + working-directory: backend + run: ruff format --check . + - name: Run tests working-directory: backend run: pytest apps/gameplay/ From 622b213be73f137b18a7443c2a50e5a5e92dc5e9 Mon Sep 17 00:00:00 2001 From: tigdav <47061880+tigdav@users.noreply.github.com> Date: Sat, 13 Jun 2026 21:59:58 +0300 Subject: [PATCH 3/3] docs(readme): add ruff badge and formatting section --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 72ed624..ff53967 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Truth or Dare [![CI](https://github.com/tigdav/truth-or-dare/actions/workflows/ci.yml/badge.svg)](https://github.com/tigdav/truth-or-dare/actions/workflows/ci.yml) +[![Ruff](https://img.shields.io/badge/code%20style-ruff-%23D7FF64?logo=ruff&logoColor=black&style=flat-square)](https://github.com/astral-sh/ruff) ![Python](https://img.shields.io/badge/Python-3.11.2-blue?logo=python&style=flat-square) ![Django](https://img.shields.io/badge/Django-5.2.15-%234092E5?logo=django&logoColor=white&style=flat-square) @@ -167,6 +168,17 @@ The test suite covers core gameplay flows and endpoint behavior. --- +## Linting & Formatting + +Code is linted and formatted with [Ruff](https://github.com/astral-sh/ruff): + +```bash +ruff check . +ruff format --check . +``` + +--- + ## Project Structure ```