From bd8fa9229b067708bc6430b2ec8dd8dc6bf32c9f Mon Sep 17 00:00:00 2001 From: sosokker Date: Sun, 17 Sep 2023 17:03:52 +0700 Subject: [PATCH] Add Tag field for Question in Admin Page --- polls/admin.py | 8 +++++--- polls/models.py | 11 +++++++++-- polls/views.py | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/polls/admin.py b/polls/admin.py index 4eb18c9..0adebad 100644 --- a/polls/admin.py +++ b/polls/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import Choice, Question +from .models import Choice, Question, Tag class ChoiceInline(admin.TabularInline): @@ -15,12 +15,14 @@ class QuestionAdmin(admin.ModelAdmin): ("End date", {"fields": ["end_date"], "classes": ["collapse"]}), ("Short Description", {"fields": ["short_description"], "classes": ["collapse"]}), ("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"] + 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 diff --git a/polls/models.py b/polls/models.py index 3fd50d5..791b85b 100644 --- a/polls/models.py +++ b/polls/models.py @@ -23,7 +23,7 @@ class Tag(models.Model): tag_text = models.CharField(max_length=50) def __str__(self): - return self.name + return self.tag_text class Question(models.Model): @@ -128,6 +128,7 @@ class Question(models.Model): @property def time_left(self): + """Return time till ending of the poll""" return self.calculate_time_left() def calculate_vote_percentage(self): @@ -143,10 +144,12 @@ class Question(models.Model): @property def up_vote_percentage(self): + """Retrieve up vote percentage from calculate_vote_percentage""" return self.calculate_vote_percentage()[0] @property def down_vote_percentage(self): + """Retrieve down vote percentage from calculate_vote_percentage""" return self.calculate_vote_percentage()[1] @property @@ -191,10 +194,12 @@ class Question(models.Model): @property def up_vote_count(self): + """Count up vote of Question""" return self.sentimentvote_set.filter(question=self, vote_types=True).count() @property def down_vote_count(self): + """Count down vote of Question""" return self.sentimentvote_set.filter(question=self, vote_types=False).count() def trending_score(self, up=None, down=None): @@ -218,7 +223,6 @@ class Question(models.Model): return score - 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 @@ -229,6 +233,9 @@ class Question(models.Model): self.trend_score = self.trending_score(up=0, down=0) super(Question, self).save(*args, **kwargs) + def get_tags(self, *args, **kwargs): + return "-".join([tag.tag_text for tag in self.tags.all()]) + class Choice(models.Model): """ diff --git a/polls/views.py b/polls/views.py index 1e3f7df..118c320 100644 --- a/polls/views.py +++ b/polls/views.py @@ -93,6 +93,10 @@ class DetailView(LoginRequiredMixin, generic.DetailView): class ResultsView(LoginRequiredMixin, generic.DetailView): + """ + Provide a view for Result page, a Result for the poll contain poll participants + number and other statistic such as up, down vote + """ model = Question template_name = "polls/results.html" @@ -110,6 +114,9 @@ class ResultsView(LoginRequiredMixin, generic.DetailView): return context class SignUpView(generic.CreateView): + """ + View that responsible for Sign Up page. + """ form_class = SignUpForm success_url = reverse_lazy('polls:index') template_name = 'registration/signup.html' @@ -167,6 +174,9 @@ def vote(request, question_id): @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) @@ -183,6 +193,9 @@ def up_down_vote(request, question_id, vote_type): # https://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django def get_client_ip(request): + """ + Use with logger to get ip of user. + """ x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] @@ -190,7 +203,12 @@ def get_client_ip(request): ip = request.META.get('REMOTE_ADDR') return ip + def search_poll(request): + """ + A function that handle the rendering of search result after user search with + search bar. + """ form = PollSearchForm results = [] @@ -199,7 +217,9 @@ def search_poll(request): form = PollSearchForm(request.GET) if form.is_valid(): q = form.cleaned_data['q'] + # Case insensitive (icontains) results = Question.objects.filter(question_text__icontains=q) + # * 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}) \ No newline at end of file