From f97a772bf319438d2a920ed879db0c796fe2f9b9 Mon Sep 17 00:00:00 2001 From: sosokker Date: Mon, 18 Sep 2023 00:11:35 +0700 Subject: [PATCH] Format file according to flake8 --- .flake8 | 12 ++++++++ polls/admin.py | 7 +++-- polls/apps.py | 5 ++-- polls/forms.py | 38 +++++++++++++++---------- polls/models.py | 19 ++++++------- polls/signals.py | 12 +++++--- polls/tests/base.py | 5 ++-- polls/tests/test_detail_views.py | 1 - polls/tests/test_question_model.py | 2 +- polls/tests/test_search_poll.py | 2 -- polls/tests/test_sentiment_model.py | 6 ++-- polls/tests/test_signup.py | 2 +- polls/tests/test_vote_views.py | 28 +++++++++---------- polls/urls.py | 4 +-- polls/views.py | 43 ++++++++++++++--------------- setup.py | 19 +++++++------ 16 files changed, 114 insertions(+), 91 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..1e5d77c --- /dev/null +++ b/.flake8 @@ -0,0 +1,12 @@ +[flake8] +max-line-length = 120 +exclude= + migrations + mysite + logs + .venv + apps.py + setup.py +per-file-ignores = + .\polls\tests\test_sentiment_model.py: E501 + .\polls\models.py: F811 \ No newline at end of file diff --git a/polls/admin.py b/polls/admin.py index 0adebad..f515a0f 100644 --- a/polls/admin.py +++ b/polls/admin.py @@ -17,12 +17,13 @@ class QuestionAdmin(admin.ModelAdmin): ("Long Description", {"fields": ["long_description"], "classes": ["collapse"]}), ("Add Tag", {"fields": ["tags"], "classes": ["collapse"]}) ] - list_display = ["question_text", "pub_date", "end_date", "was_published_recently", "can_vote", "trending_score", "get_tags"] + list_display = ["question_text", "pub_date", "end_date", "was_published_recently", "can_vote", + "trending_score", "get_tags"] inlines = [ChoiceInline] list_filter = ["pub_date", "end_date"] search_fields = ["question_text"] + # https://stackoverflow.com/questions/10904848/adding-inline-many-to-many-objects-in-django-admin admin.site.register(Question, QuestionAdmin) -admin.site.register(Tag) # Add Field to modify tags objects in Question - \ No newline at end of file +admin.site.register(Tag) # Add Field to modify tags objects in Question diff --git a/polls/apps.py b/polls/apps.py index ab3fd84..36439c3 100644 --- a/polls/apps.py +++ b/polls/apps.py @@ -4,6 +4,7 @@ from django.apps import AppConfig class PollsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'polls' - + def ready(self) -> None: - import polls.signals \ No newline at end of file + import polls.signals + \ No newline at end of file diff --git a/polls/forms.py b/polls/forms.py index 636f285..824b171 100644 --- a/polls/forms.py +++ b/polls/forms.py @@ -7,18 +7,19 @@ from django.contrib.auth.models import User from .models import Question, Tag + class SignUpForm(UserCreationForm): - tailwind_class = "w-full border-2 border-gray-300 bg-gray-100 rounded-lg focus:ring focus:border-blue-300 focus:shadow-none" + tailwind_class = """w-full border-2 border-gray-300 bg-gray-100 rounded-lg + focus:ring focus:border-blue-300 focus:shadow-none""" logger = logging.getLogger('signup_form') - username = forms.CharField(widget=forms.TextInput(attrs={'class': tailwind_class}), - error_messages={ - 'unique': 'This username is already in use.', - 'invalid': 'Invalid username format.', - 'max_length': 'Username should not exceed 150 characters.', + username = forms.CharField(widget=forms.TextInput(attrs={'class': tailwind_class}), error_messages={ + 'unique': 'This username is already in use.', + 'invalid': 'Invalid username format.', + 'max_length': 'Username should not exceed 150 characters.', } ) password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class': tailwind_class}), - error_messages={'min_length': 'Password must contain at least 8 characters.',} + error_messages={'min_length': 'Password must contain at least 8 characters.', } ) password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': tailwind_class}),) @@ -49,15 +50,24 @@ class PollSearchForm(forms.Form): class PollCreateForm(forms.ModelForm): - box_style = "w-full py-2 px-2 border-2 border-gray-300 bg-gray-100 rounded-lg focus:ring focus:border-blue-300 focus:shadow-none" - large_box_style = "w-full border-2 border-gray-300 bg-gray-100 rounded-lg focus:ring focus:border-blue-300 focus:shadow-none" + box_style = """w-full py-2 px-2 border-2 border-gray-300 bg-gray-100 rounded-lg + focus:ring focus:border-blue-300 focus:shadow-none""" + large_box_style = """w-full border-2 border-gray-300 bg-gray-100 rounded-lg + focus:ring focus:border-blue-300 focus:shadow-none""" - question_text = forms.CharField(min_length=10, max_length=100, required=True, - widget=forms.TextInput(attrs={'class':box_style, 'placeholder':"What is your question?"})) + question_text = forms.CharField(min_length=10, max_length=100, required=True, + widget=forms.TextInput(attrs={'class': box_style, + 'placeholder': "What is your question?"})) pub_date = forms.DateTimeField(widget=forms.DateInput(attrs={'type': 'date'})) end_date = forms.DateTimeField(widget=forms.DateInput(attrs={'type': 'date'})) - short_description = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class':box_style, 'placeholder':"Short description (Maximum 200 characters)"})) - long_description = forms.CharField(max_length=2000, widget=forms.Textarea(attrs={'class':large_box_style, 'placeholder':"Long description (Maximum 2000 characters)"})) + short_description = forms.CharField(max_length=200, + widget=forms.TextInput( + attrs={'class': box_style, + 'placeholder': "Short description (Maximum 200 characters)"})) + long_description = forms.CharField(max_length=2000, + widget=forms.Textarea( + attrs={'class': large_box_style, + 'placeholder': "Long description (Maximum 2000 characters)"})) tags = forms.MultipleChoiceField( choices=[(tag.id, tag.tag_text) for tag in Tag.objects.all()], widget=forms.CheckboxSelectMultiple, @@ -69,7 +79,7 @@ class PollCreateForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + class Meta: model = Question fields = ['question_text', 'pub_date', 'end_date', 'short_description', 'long_description', 'tags'] - \ No newline at end of file diff --git a/polls/models.py b/polls/models.py index 78adb50..670fbb2 100644 --- a/polls/models.py +++ b/polls/models.py @@ -12,7 +12,6 @@ Attributes: from django.db import models, IntegrityError from django.utils import timezone from django.contrib import admin -from django.db.models import Sum from django.contrib.auth.models import User @@ -169,7 +168,7 @@ class Question(models.Model): self.save() except IntegrityError: vote = self.sentimentvote_set.filter(user=user) - if vote[0].vote_types == False: + if vote[0].vote_types is False: vote.update(vote_types=True) self.save() else: @@ -185,7 +184,7 @@ class Question(models.Model): self.save() except IntegrityError: vote = self.sentimentvote_set.filter(user=user) - if vote[0].vote_types == True: + if vote[0].vote_types is True: vote.update(vote_types=False) self.save() else: @@ -207,8 +206,8 @@ class Question(models.Model): published_date_duration = timezone.now() - self.pub_date score = 0 - if (published_date_duration.seconds < 259200): # Second unit - score += 100 + if (published_date_duration.seconds < 259200): # Second unit + score += 100 elif (published_date_duration.seconds < 604800): score += 75 elif (published_date_duration.seconds < 2592000): @@ -216,7 +215,7 @@ class Question(models.Model): else: score += 25 - if (up == None) and (down == None): + if (up is None) and (down is None): score += ((self.up_vote_count/5) - (self.down_vote_count/5)) * 100 else: score += ((up/5) - (down/5)) * 100 @@ -226,10 +225,10 @@ class Question(models.Model): def get_tags(self, *args, **kwargs): return "-".join([tag.tag_text for tag in self.tags.all()]) - def save(self, *args, **kwargs): """Modify save method of Question object""" - # to-be-added instance # * https://github.com/django/django/blob/866122690dbe233c054d06f6afbc2f3cc6aea2f2/django/db/models/base.py#L447 + # to-be-added instance + # * https://github.com/django/django/blob/866122690dbe233c054d06f6afbc2f3cc6aea2f2/django/db/models/base.py#L447 if self._state.adding: try: self.trend_score = self.trending_score() @@ -271,7 +270,7 @@ class Vote(models.Model): def __str__(self): return f"{self.user} voted for {self.choice} in {self.question}" - + # ! Most of the code from https://stackoverflow.com/a/70869267 class SentimentVote(models.Model): @@ -296,4 +295,4 @@ class SentimentVote(models.Model): unique_together (list of str): Ensures that a user can only cast one sentiment vote (upvote or downvote) for a specific question. """ - unique_together = ['user', 'question'] \ No newline at end of file + unique_together = ['user', 'question'] diff --git a/polls/signals.py b/polls/signals.py index 4f63242..8d5ed97 100644 --- a/polls/signals.py +++ b/polls/signals.py @@ -4,6 +4,7 @@ from django.dispatch import receiver log = logging.getLogger("django") + def get_client_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: @@ -12,9 +13,10 @@ def get_client_ip(request): ip = request.META.get('REMOTE_ADDR') return ip -#! https://stackoverflow.com/questions/37618473/how-can-i-log-both-successful-and-failed-login-and-logout-attempts-in-django + +# !https://stackoverflow.com/questions/37618473/how-can-i-log-both-successful-and-failed-login-and-logout-attempts-in-django @receiver(user_logged_in) -def user_logged_in_callback(sender, request, user, **kwargs): +def user_logged_in_callback(sender, request, user, **kwargs): ip = get_client_ip(request) log.info('Login User: {user} via ip: {ip}'.format( @@ -22,8 +24,9 @@ def user_logged_in_callback(sender, request, user, **kwargs): ip=ip )) + @receiver(user_logged_out) -def user_logged_out_callback(sender, request, user, **kwargs): +def user_logged_out_callback(sender, request, user, **kwargs): ip = get_client_ip(request) log.info('Logout User: {user} via ip: {ip}'.format( @@ -31,8 +34,9 @@ def user_logged_out_callback(sender, request, user, **kwargs): ip=ip )) + @receiver(user_login_failed) def user_login_failed_callback(sender, credentials, **kwargs): log.warning('Login Failed for: {credentials}'.format( credentials=credentials, - )) \ No newline at end of file + )) diff --git a/polls/tests/base.py b/polls/tests/base.py index 1e2db85..d1e06d6 100644 --- a/polls/tests/base.py +++ b/polls/tests/base.py @@ -1,7 +1,6 @@ from django.utils import timezone -from django.contrib.auth.models import User -from ..models import Question, Vote, Choice +from ..models import Question def create_question(question_text, day=0): @@ -11,4 +10,4 @@ def create_question(question_text, day=0): in the past, positive for questions that have yet to be published). """ time = timezone.now() + timezone.timedelta(days=day) - return Question.objects.create(question_text=question_text, pub_date=time) \ No newline at end of file + return Question.objects.create(question_text=question_text, pub_date=time) diff --git a/polls/tests/test_detail_views.py b/polls/tests/test_detail_views.py index db2f3bc..07895ee 100644 --- a/polls/tests/test_detail_views.py +++ b/polls/tests/test_detail_views.py @@ -1,5 +1,4 @@ from django.test import TestCase, Client -from django.utils import timezone from django.urls import reverse from django.contrib.auth.models import User diff --git a/polls/tests/test_question_model.py b/polls/tests/test_question_model.py index f0cdd07..750dbab 100644 --- a/polls/tests/test_question_model.py +++ b/polls/tests/test_question_model.py @@ -102,4 +102,4 @@ class QuestionModelTests(TestCase): pub_date = timezone.now() - datetime.timedelta(hours=1) end_date = timezone.now() + datetime.timedelta(hours=2) question = Question(pub_date=pub_date, end_date=end_date) - self.assertIs(question.can_vote(), True) \ No newline at end of file + self.assertIs(question.can_vote(), True) diff --git a/polls/tests/test_search_poll.py b/polls/tests/test_search_poll.py index 1340965..a8709a8 100644 --- a/polls/tests/test_search_poll.py +++ b/polls/tests/test_search_poll.py @@ -2,7 +2,6 @@ from django.test import TestCase from django.urls import reverse from ..models import Question -from ..views import search_poll class SearchPollTest(TestCase): @@ -22,4 +21,3 @@ class SearchPollTest(TestCase): data = {'q': ''} response = self.client.get(reverse("polls:search_poll"), data) self.assertQuerysetEqual(response.context['results'], Question.objects.all()) - diff --git a/polls/tests/test_sentiment_model.py b/polls/tests/test_sentiment_model.py index c1ede3b..97bae5f 100644 --- a/polls/tests/test_sentiment_model.py +++ b/polls/tests/test_sentiment_model.py @@ -2,7 +2,7 @@ from django.test import TransactionTestCase, Client from django.contrib.auth.models import User from .base import create_question -from ..views import up_down_vote + # ! https://stackoverflow.com/questions/24588520/testing-several-integrityerrors-in-the-same-django-unittest-test-case # * https://stackoverflow.com/questions/44450533/difference-between-testcase-and-transactiontestcase-classes-in-django-test @@ -32,11 +32,11 @@ class UpDownVoteViewTest(TransactionTestCase): self.assertEqual(count_up, 0) self.assertEqual(count_down, 1) - def test_can_change_up_to_down(self): + def test_can_change_down_to_up(self): self.client.login(username="test_user", password="12345abc") self.q1.downvote(self.user) self.q1.upvote(self.user) count_up = self.q1.sentimentvote_set.filter(vote_types=True).count() count_down = self.q1.sentimentvote_set.filter(vote_types=False).count() self.assertEqual(count_up, 1) - self.assertEqual(count_down, 0) \ No newline at end of file + self.assertEqual(count_down, 0) diff --git a/polls/tests/test_signup.py b/polls/tests/test_signup.py index 50278ee..c9bd074 100644 --- a/polls/tests/test_signup.py +++ b/polls/tests/test_signup.py @@ -42,4 +42,4 @@ class SignUpTestCase(TestCase): 'password2': 'testpassword123', } response = self.client.post(signup_url, data) - self.assertRedirects(response, reverse("polls:index")) \ No newline at end of file + self.assertRedirects(response, reverse("polls:index")) diff --git a/polls/tests/test_vote_views.py b/polls/tests/test_vote_views.py index 393650e..af8b3c3 100644 --- a/polls/tests/test_vote_views.py +++ b/polls/tests/test_vote_views.py @@ -5,6 +5,7 @@ from django.contrib.auth.models import User from .base import create_question from ..models import Vote, Choice + class VoteViewTest(TestCase): @classmethod def setUpTestData(cls): @@ -20,9 +21,9 @@ class VoteViewTest(TestCase): """ self.client.login(username=self.user.username, password="aaa123321aaa") - response = self.client.post(reverse("polls:vote", args=(self.question.id,)), - {'choice' : self.choice1.id}) - + response = self.client.post(reverse("polls:vote", args=(self.question.id,)), + {'choice': self.choice1.id}) + self.assertRedirects(response, reverse("polls:results", args=(self.question.id,))) self.assertTrue(Vote.objects.filter(user=self.user, question=self.question).exists()) @@ -32,18 +33,18 @@ class VoteViewTest(TestCase): """ self.client.login(username=self.user.username, password="aaa123321aaa") - response = self.client.post(reverse("polls:vote", args=(self.question.id,)), - {'choice' : 1000}) - + response = self.client.post(reverse("polls:vote", args=(self.question.id,)), + {'choice': 1000}) + self.assertRedirects(response, reverse('polls:detail', args=(self.question.id,))) def test_vote_without_login(self): """ Test the vote view when the user is not logged in. """ - response = self.client.post(reverse("polls:vote", args=(self.question.id,)), - {'choice' : self.choice1}) - + response = self.client.post(reverse("polls:vote", args=(self.question.id,)), + {'choice': self.choice1}) + self.assertRedirects(response, "/accounts/login/?next=/polls/1/vote/") def test_vote_voting_not_allowed(self): @@ -55,9 +56,8 @@ class VoteViewTest(TestCase): self.question_2 = create_question(question_text="Test not allow", day=10) self.choice_2 = Choice.objects.create(question=self.question_2, choice_text="Test Choice 2_2") - response = self.client.post(reverse("polls:vote", args=(self.question_2.id,)), - {"choice" : self.choice_2.id}) - + response = self.client.post(reverse("polls:vote", args=(self.question_2.id,)), {"choice": self.choice_2.id}) + self.assertRedirects(response, reverse('polls:index')) def test_vote_with_no_post_data(self): @@ -81,6 +81,6 @@ class VoteViewTest(TestCase): response_2 = self.client.post(reverse("polls:vote", args=(self.question.id,)), {"choice": self.choice2.id}) self.assertRedirects(response_2, reverse('polls:results', args=(self.question.id,))) - + self.assertFalse(Vote.objects.filter(user=self.user, question=self.question, choice=self.choice1).exists()) - self.assertTrue(Vote.objects.filter(user=self.user, question=self.question, choice=self.choice2).exists()) \ No newline at end of file + self.assertTrue(Vote.objects.filter(user=self.user, question=self.question, choice=self.choice2).exists()) diff --git a/polls/urls.py b/polls/urls.py index 8ab0dd6..8737085 100644 --- a/polls/urls.py +++ b/polls/urls.py @@ -9,8 +9,8 @@ urlpatterns = [ path("/results/", views.ResultsView.as_view(), name="results"), path("/vote/", views.vote, name="vote"), path("signup/", views.SignUpView.as_view(), name="signup"), - path("upvote/", views.up_down_vote, {'vote_type' : 'upvote'}, name="upvote"), - path("downvote/", views.up_down_vote, {'vote_type' : 'downvote'}, name="downvote"), + path("upvote/", views.up_down_vote, {'vote_type': 'upvote'}, name="upvote"), + path("downvote/", views.up_down_vote, {'vote_type': 'downvote'}, name="downvote"), path("search", views.search_poll, name="search_poll"), path("create", views.create_poll, name="create_poll") ] diff --git a/polls/views.py b/polls/views.py index 4e1d5b9..43028ae 100644 --- a/polls/views.py +++ b/polls/views.py @@ -2,7 +2,6 @@ import logging from typing import Any from django.shortcuts import get_object_or_404, render, redirect -from django.urls import reverse from django.views import generic from django.utils import timezone from django.urls import reverse_lazy, reverse @@ -26,21 +25,21 @@ class IndexView(generic.ListView): context_object_name = "latest_question_list" def get_queryset(self): - """ - Return the last published questions that is published and haven't ended yet. - """ - now = timezone.now() - all_poll_queryset = Question.objects.filter( - Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None))) - ).order_by("-pub_date") + """ + Return the last published questions that is published and haven't ended yet. + """ + now = timezone.now() + all_poll_queryset = Question.objects.filter( + Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None))) + ).order_by("-pub_date") - trend_poll_queryset = Question.objects.filter( - Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None))) & Q(trend_score__gte=100) - ).order_by("trend_score", "end_date")[:3] + trend_poll_queryset = Question.objects.filter( + Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None))) & Q(trend_score__gte=100) + ).order_by("trend_score")[:3] - queryset = {'all_poll' : all_poll_queryset, - 'trend_poll' : trend_poll_queryset,} - return queryset + queryset = {'all_poll': all_poll_queryset, + 'trend_poll': trend_poll_queryset, } + return queryset class DetailView(LoginRequiredMixin, generic.DetailView): @@ -102,7 +101,7 @@ class ResultsView(LoginRequiredMixin, generic.DetailView): def get_context_data(self, **kwargs: Any) -> dict[str, Any]: context = super().get_context_data(**kwargs) - + user_voted = None question = self.get_object() if question.sentimentvote_set.filter(user=self.request.user, question=question, vote_types=True).exists(): @@ -113,6 +112,7 @@ class ResultsView(LoginRequiredMixin, generic.DetailView): context['user_voted'] = user_voted return context + class SignUpView(generic.CreateView): """ View that responsible for Sign Up page. @@ -153,7 +153,7 @@ def vote(request, question_id): vote, created = Vote.objects.update_or_create( user=request.user, question=question, - defaults={'choice' : selected_choice} + defaults={'choice': selected_choice} ) if created: @@ -170,16 +170,15 @@ def vote(request, question_id): else: messages.error(request, "Invalid request method.") return redirect("polls:index") - + @login_required def up_down_vote(request, question_id, vote_type): """ A function that control the upvote and downvote request. """ - ip = get_client_ip(request) question = get_object_or_404(Question, pk=question_id) - + if request.method == "POST": if vote_type == "upvote": if question.upvote(request.user): @@ -187,7 +186,7 @@ def up_down_vote(request, question_id, vote_type): elif vote_type == "downvote": if question.downvote(request.user): messages.success(request, "You downvoted this Poll😭") - + return redirect(reverse("polls:results", args=(question_id,))) @@ -207,7 +206,7 @@ def get_client_ip(request): def search_poll(request): """ A function that handle the rendering of search result after user search with - search bar. + search bar. """ form = PollSearchForm @@ -222,7 +221,7 @@ def search_poll(request): # * If user search with empty string then show every poll. if q == '': results = Question.objects.all() - return render(request, 'polls/search.html', {'form':form, 'results':results, 'q':q}) + return render(request, 'polls/search.html', {'form': form, 'results': results, 'q': q}) @login_required diff --git a/setup.py b/setup.py index 9866a7a..8bb23d7 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def check_python_command(): return command except FileNotFoundError: continue - + return None def create_virtual_environment(env_name, python_command): @@ -31,7 +31,7 @@ def customize_virtual_environment(): def setup_environment_variables(python_command_in_venv): print("Setting up Django environment variables:") - + # SECRET KEY generate_secret_key = input("Generate a Django SECRET_KEY? (yes/no): ").strip().lower() if generate_secret_key == "yes": @@ -39,7 +39,7 @@ def setup_environment_variables(python_command_in_venv): 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())']).decode().strip() else: secret_key = input("Enter Django SECRET_KEY: ").strip() - + # DEBUG MODE while True: debug_mode = input("Enable DEBUG mode? (True/False): ").strip() @@ -52,7 +52,7 @@ def setup_environment_variables(python_command_in_venv): allowed_hosts = input("Enter ALLOWED_HOSTS (comma-separated, or press Enter for default): ").strip() if not allowed_hosts: allowed_hosts = "*.ku.th,localhost,127.0.0.1,::1" - + # TZ available_time_zones = ["Asia/Bangkok", "Japan", "UCT", "CST6CDT", "Custom"] @@ -73,7 +73,7 @@ def setup_environment_variables(python_command_in_venv): print("Invalid choice. Please enter a valid number.") except ValueError: print("Invalid input. Please enter a valid number.") - + email_host_password = input("Enter EMAIL_HOST_PASSWORD: ").strip() # SET @@ -116,7 +116,7 @@ def main(): elif is_windows: activate_command = os.path.join(".venv", "Scripts", "activate") subprocess.run([activate_command], shell=True) - + python_command = os.path.join(".venv", "bin", "python") if is_posix else os.path.join(".venv", "Scripts", "python") else: print("Not setting up a virtual environment. Using the global Python interpreter.") @@ -154,19 +154,19 @@ def main(): print(f"==========================Install Requirement==========================") subprocess.run([python_command_in_venv, "-m", "pip", "install", "-r", "requirements.txt"]) setup_environment_variables(python_command_in_venv) - + subprocess.run([python_command_in_venv, "-m", "pip", "install", "-r", "requirements.txt"], check=True) subprocess.run([python_command_in_venv, "manage.py", "migrate"], check=True) subprocess.run([python_command_in_venv, "manage.py", "loaddata", "data/users.json"], check=True) subprocess.run([python_command_in_venv, "manage.py", "loaddata", "data/polls.json"], check=True) - + start_server = input("Do you want to start the Django server? (yes/no): ").strip().lower() if start_server == "yes": print("=================================================") print("Django run in --insecure mode to load Static File") print("==================================================") subprocess.run([python_command_in_venv, "manage.py", "runserver", "--insecure"], check=True) - + except subprocess.CalledProcessError as e: print(f"Error: {e}") sys.exit(1) @@ -174,5 +174,6 @@ def main(): print("\nSetup process aborted.") sys.exit(1) + if __name__ == "__main__": main()