2 Komitmen 511d59b058 ... ae6160de09

Pembuat SHA1 Pesan Tanggal
  Adam Day ae6160de09 Added a basic results page. 2 tahun lalu
  Adam Day c946a69e3c Added images to questions 2 tahun lalu

+ 3 - 1
.gitignore

@@ -1,3 +1,5 @@
 .idea
 *.db
-*.sqlite3
+*.sqlite3
+/media/
+

+ 2 - 0
askpatrons/settings.py

@@ -126,6 +126,8 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
 #STATIC_ROOT = BASE_DIR / 'static'
 
 
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
 
 
 # Default primary key field type

+ 4 - 0
askpatrons/urls.py

@@ -15,8 +15,12 @@ Including another URLconf
 """
 from django.contrib import admin
 from django.urls import path, include
+from django.conf import settings
+from django.conf.urls.static import static
 
 urlpatterns = [
     path('admin/', admin.site.urls),
     path('', include('vote.urls')),
 ]
+
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

TEMPAT SAMPAH
requirements.txt


+ 1 - 1
vote/admin.py

@@ -21,7 +21,7 @@ admin.site.register(ZipCode, ZipCodeAdmin)
 admin.site.register(AgeRange)
 admin.site.register(Voter)
 admin.site.register(Question)
+admin.site.register(QuestionImage)
 admin.site.register(Vote)
 admin.site.register(VoterQuestion)
 
-

+ 14 - 0
vote/models.py

@@ -66,6 +66,20 @@ class Question(models.Model):
     class Meta:
         ordering = ['pub_date']
 
+    def images(self):
+        return QuestionImage.objects.filter(question=self)
+
+
+class QuestionImage(models.Model):
+    question = models.ForeignKey(Question, on_delete=models.CASCADE)
+    image = models.ImageField(upload_to='media/questions/images')
+
+    def __str__(self):
+        return "%s (%s)" % (self.question, self.image)
+
+    class Meta:
+        ordering = ['question']
+
 
 class Vote(models.Model):
     question = models.ForeignKey(Question, on_delete=models.CASCADE)

+ 18 - 0
vote/templates/vote/dark-layout.html

@@ -0,0 +1,18 @@
+{% load static %}
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>AskPatron</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
+    <link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
+    <link href="{% static '/css/app.css' %}" rel="stylesheet">
+  </head>
+  <body class="bg-dark">
+    {% block content %}{% endblock %}
+    <script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
+    <script src="{% static '/js/app.js' %}"></script>
+  </body>
+</html>

+ 16 - 2
vote/templates/vote/index.html

@@ -1,5 +1,6 @@
 {% extends 'vote/layout.html' %}
 {% load django_bootstrap5 %}
+{% load static %}
 
 {% block content %}
 <form action="" method="post">
@@ -12,12 +13,25 @@
                         <div class="poll-question">
                             {{ question }}
                         </div>
+                        {% if question.images %}
+                        <div class="poll-images mb-5">
+                            <div class="row justify-content-center">
+                            {% for image in question.images.all %}
+                                <div class="col-sm-12 col-md-4 col-lg-2 text-center">
+                                    <div class="card">
+                                        <img src="{{ image.image.url }}" alt="" class="card-image">
+                                    </div>
+                                </div>
+                            {% endfor %}
+                            </div>
+                        </div>
+                        {% endif %}
                         <div class="text-center">
                             <input type="radio" class="btn-check" value="no" name="{{ question.question_id }}" id="no-{{ forloop.counter0 }}" autocomplete="off">
-                            <label class="btn btn-outline-danger button_no" for="no-{{ forloop.counter0 }}">No</label>
+                            <label class="btn btn-outline-danger button_no mb-5" for="no-{{ forloop.counter0 }}">No</label>
 
                             <input type="radio" class="btn-check" value="yes" name="{{ question.question_id }}" id="yes-{{ forloop.counter0 }}" autocomplete="off">
-                            <label class="btn btn-outline-success button_yes" for="yes-{{ forloop.counter0 }}">Yes</label>
+                            <label class="btn btn-outline-success button_yes mb-5" for="yes-{{ forloop.counter0 }}">Yes</label>
                         </div>
                     </div>
                 {% endfor %}

+ 48 - 13
vote/templates/vote/results.html

@@ -1,18 +1,53 @@
-{% extends 'vote/layout.html' %}
+{% extends 'vote/dark-layout.html' %}
+
 {% block content %}
-    <div class="container">
-        <div class="row">
-            <div class="col text-center mt-5 pt-5">
-                <h1 class="display-1">Thank you for your submission.</h1>
-                <a class="btn btn-lg btn-primary" href="{% url 'index' %}">Start a submission</a>
+    <div class="container p-5">
+        <div class="row justify-content-center">
+            <div class="col-sm-12 col-md-6">
+                <div class="text-center">
+                    <h1 class="text-light">Results</h1>
+                </div>
+                <div class="card">
+                    <div class="card-body p-5">
+                        {% for question in questions %}
+                            Posted {{ question.pub_date }}
+                            <p class="lead">{{ question.question_text }}</p>
+                            <div class="row mb-5 pb-5 border-bottom">
+                                <div class="col-4 text-center">
+                                    <div class="card">
+                                        <div class="card-body">
+                                            <p>
+                                                Total
+                                                <h1>{{ question.total_votes }}</h1>
+                                            </p>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="col-4 text-center">
+                                    <div class="card {% if question.yes_votes > question.no_votes %} text-bg-success {% else %} border-success text-success {% endif %}">
+                                        <div class="card-body">
+                                            <p>
+                                                In Favor
+                                                <h1>{{ question.yes_votes }}</h1>
+                                            </p>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="col-4 text-center">
+                                    <div class="card {% if question.no_votes > question.yes_votes %} text-bg-danger {% else %} border-danger text-danger {% endif %}">
+                                        <div class="card-body">
+                                            <p>
+                                                Opposed
+                                                <h1>{{ question.no_votes }}</h1>
+                                            </p>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        {% endfor %}
+                    </div>
+                </div>
             </div>
         </div>
     </div>
-
-    <script>
-        // Redirect after 10 seconds
-        setTimeout(function() {
-            window.location.href = "/";
-        }, 10000);
-    </script>
 {% endblock %}

+ 18 - 0
vote/templates/vote/thankyou.html

@@ -0,0 +1,18 @@
+{% extends 'vote/layout.html' %}
+{% block content %}
+    <div class="container">
+        <div class="row">
+            <div class="col text-center mt-5 pt-5">
+                <h1 class="display-1">Thank you for your submission.</h1>
+                <a class="btn btn-lg btn-primary" href="{% url 'index' %}">Start a submission</a>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        // Redirect after 10 seconds
+        setTimeout(function() {
+            window.location.href = "/";
+        }, 10000);
+    </script>
+{% endblock %}

+ 1 - 0
vote/urls.py

@@ -3,4 +3,5 @@ from . import views
 
 urlpatterns = [
     path('', views.index, name='index'),
+    path('results/', views.results, name='results'),
 ]

+ 19 - 2
vote/views.py

@@ -41,7 +41,6 @@ def index(request):
 
                 # Check if voter has already voted on this question
                 for question in questions:
-                    print(question)
                     voter_question = VoterQuestion.objects.filter(voter=voter, question=question).first()
                     if voter_question is None:
                         # Add the voter to the VoterQuestion table
@@ -53,7 +52,7 @@ def index(request):
                         vote.save()
 
                 # Redirect to the results page
-                return render(request, 'vote/results.html')
+                return render(request, 'vote/thankyou.html')
 
     questions = Question.objects.all()
 
@@ -63,3 +62,21 @@ def index(request):
     }
 
     return render(request, 'vote/index.html', context=context)
+
+
+def results(request):
+
+    # Tally the votes for each question
+    questions = Question.objects.all()
+    for question in questions:
+        yes_votes = Vote.objects.filter(question=question, vote=True).count()
+        no_votes = Vote.objects.filter(question=question, vote=False).count()
+        question.total_votes = yes_votes + no_votes
+        question.yes_votes = yes_votes
+        question.no_votes = no_votes
+
+    context = {
+        'questions': questions,
+    }
+
+    return render(request, 'vote/results.html', context=context)