Spaces:
Sleeping
Sleeping
made public polling working and also shows result
Browse files- accounts/admin.py +2 -2
- accounts/migrations/0003_user_joining_date.py +19 -0
- accounts/models.py +2 -0
- newdata.json +1 -0
- polls/admin.py +20 -9
- polls/forms.py +9 -0
- polls/migrations/0002_question_author.py +22 -0
- polls/migrations/0003_remove_choice_votes_votes.py +28 -0
- polls/migrations/0004_rename_votes_vote.py +19 -0
- polls/models.py +22 -3
- polls/static/polls/create.css +160 -0
- polls/static/polls/create.js +164 -0
- polls/static/polls/header.css +77 -0
- polls/static/polls/index.css +36 -83
- polls/static/polls/index.js +100 -0
- polls/static/polls/your_polls.css +180 -0
- polls/static/polls/your_polls.js +64 -0
- polls/templates/polls/base.html +16 -0
- polls/templates/polls/create.html +55 -0
- polls/templates/polls/header.html +16 -0
- polls/templates/polls/index.html +21 -29
- polls/templates/polls/your_polls.html +78 -0
- polls/templatetags/__init__.py +0 -0
- polls/templatetags/index.py +7 -0
- polls/urls.py +8 -1
- polls/views.py +73 -23
accounts/admin.py
CHANGED
|
@@ -10,8 +10,8 @@ from .forms import UserAdminCreationForm,UserAdminUpdateForm
|
|
| 10 |
class MyUserAdmin(admin.ModelAdmin):
|
| 11 |
|
| 12 |
search_fields=('email','username')
|
| 13 |
-
|
| 14 |
-
list_display = ('email','username','is_active','is_staff','is_superuser')
|
| 15 |
|
| 16 |
# fieldsets=((None,{'fields':('email','username')}),
|
| 17 |
# (None,{'fields':('password',)}))
|
|
|
|
| 10 |
class MyUserAdmin(admin.ModelAdmin):
|
| 11 |
|
| 12 |
search_fields=('email','username')
|
| 13 |
+
ordering=('-joining_date',)
|
| 14 |
+
list_display = ('email','username','joining_date','is_active','is_staff','is_superuser')
|
| 15 |
|
| 16 |
# fieldsets=((None,{'fields':('email','username')}),
|
| 17 |
# (None,{'fields':('password',)}))
|
accounts/migrations/0003_user_joining_date.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 4.2.3 on 2023-07-27 01:18
|
| 2 |
+
|
| 3 |
+
from django.db import migrations, models
|
| 4 |
+
import django.utils.timezone
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class Migration(migrations.Migration):
|
| 8 |
+
|
| 9 |
+
dependencies = [
|
| 10 |
+
('accounts', '0002_alter_user_is_active'),
|
| 11 |
+
]
|
| 12 |
+
|
| 13 |
+
operations = [
|
| 14 |
+
migrations.AddField(
|
| 15 |
+
model_name='user',
|
| 16 |
+
name='joining_date',
|
| 17 |
+
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='Joining Date'),
|
| 18 |
+
),
|
| 19 |
+
]
|
accounts/models.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
from django.db import models
|
|
|
|
| 2 |
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
|
| 3 |
|
| 4 |
|
|
@@ -38,6 +39,7 @@ class User(AbstractBaseUser,PermissionsMixin):
|
|
| 38 |
|
| 39 |
email = models.EmailField(verbose_name="Email Address",primary_key=True,max_length=255,unique=True)
|
| 40 |
username = models.CharField("Name",max_length=150,unique=False)
|
|
|
|
| 41 |
is_staff = models.BooleanField(default=False)
|
| 42 |
is_superuser = models.BooleanField(default=False)
|
| 43 |
is_active = models.BooleanField(default=True)
|
|
|
|
| 1 |
from django.db import models
|
| 2 |
+
from django.utils import timezone
|
| 3 |
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
|
| 4 |
|
| 5 |
|
|
|
|
| 39 |
|
| 40 |
email = models.EmailField(verbose_name="Email Address",primary_key=True,max_length=255,unique=True)
|
| 41 |
username = models.CharField("Name",max_length=150,unique=False)
|
| 42 |
+
joining_date = models.DateTimeField("Joining Date",default=timezone.now)
|
| 43 |
is_staff = models.BooleanField(default=False)
|
| 44 |
is_superuser = models.BooleanField(default=False)
|
| 45 |
is_active = models.BooleanField(default=True)
|
newdata.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[{"model": "polls.question", "pk": 1, "fields": {"author": "panthrianuj@gmail.com", "question_text": "What is your age group ?", "pub_date": "2023-07-26T08:45:41Z"}}, {"model": "polls.question", "pk": 2, "fields": {"author": "panthrianuj@gmail.com", "question_text": "who do you love the most?", "pub_date": "2023-07-26T09:44:13Z"}}, {"model": "polls.question", "pk": 3, "fields": {"author": "panthrianuj@gmail.com", "question_text": "which laptop is the best ?", "pub_date": "2023-07-26T16:24:56Z"}}, {"model": "polls.question", "pk": 4, "fields": {"author": "panthriankur@gmail.com", "question_text": "new question ?", "pub_date": "2023-07-28T06:10:51.731Z"}}, {"model": "polls.question", "pk": 8, "fields": {"author": "panthrianuj@gmail.com", "question_text": "dffg", "pub_date": "2023-07-28T09:01:45.976Z"}}, {"model": "polls.question", "pk": 9, "fields": {"author": "panthrianuj@gmail.com", "question_text": "dffg", "pub_date": "2023-07-28T09:02:31.530Z"}}, {"model": "polls.choice", "pk": 1, "fields": {"question": 1, "choice_text": "under 15"}}, {"model": "polls.choice", "pk": 2, "fields": {"question": 1, "choice_text": "16-18"}}, {"model": "polls.choice", "pk": 3, "fields": {"question": 1, "choice_text": "20-24"}}, {"model": "polls.choice", "pk": 4, "fields": {"question": 2, "choice_text": "Friends"}}, {"model": "polls.choice", "pk": 5, "fields": {"question": 2, "choice_text": "Family"}}, {"model": "polls.choice", "pk": 6, "fields": {"question": 3, "choice_text": "Acer"}}, {"model": "polls.choice", "pk": 7, "fields": {"question": 3, "choice_text": "Msi"}}, {"model": "polls.choice", "pk": 8, "fields": {"question": 3, "choice_text": "Hp"}}, {"model": "polls.choice", "pk": 9, "fields": {"question": 3, "choice_text": "Dell"}}, {"model": "polls.choice", "pk": 10, "fields": {"question": 3, "choice_text": "Asus"}}, {"model": "polls.choice", "pk": 11, "fields": {"question": 4, "choice_text": "me"}}, {"model": "polls.choice", "pk": 12, "fields": {"question": 4, "choice_text": "you"}}, {"model": "polls.choice", "pk": 19, "fields": {"question": 8, "choice_text": "{{ choice.choice_text }}"}}, {"model": "polls.choice", "pk": 20, "fields": {"question": 8, "choice_text": "{{ choice.choice_text }}"}}, {"model": "polls.choice", "pk": 21, "fields": {"question": 8, "choice_text": "{{ choice.choice_text }}"}}, {"model": "polls.choice", "pk": 22, "fields": {"question": 9, "choice_text": "{{ choice.choice_text }}"}}, {"model": "polls.choice", "pk": 23, "fields": {"question": 9, "choice_text": "{{ choice.choice_text }}"}}, {"model": "polls.choice", "pk": 24, "fields": {"question": 9, "choice_text": "{{ choice.choice_text }}"}}]
|
polls/admin.py
CHANGED
|
@@ -1,21 +1,32 @@
|
|
| 1 |
from django.contrib import admin
|
| 2 |
-
from .models import Question,Choice
|
| 3 |
|
| 4 |
|
| 5 |
class ChoiceInline(admin.TabularInline):
|
| 6 |
-
|
| 7 |
-
model=Choice
|
| 8 |
-
extra=2
|
| 9 |
|
| 10 |
class QuestionAdmin(admin.ModelAdmin):
|
| 11 |
-
# fields=['question_text','pub_date']
|
| 12 |
-
|
| 13 |
-
fieldsets=[("question",{"fields":['question_text']}),
|
| 14 |
-
("Date information",{"fields":['pub_date']})]
|
| 15 |
|
| 16 |
inlines = [ChoiceInline]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
|
| 19 |
# Register your models here.
|
| 20 |
admin.site.register(Question,QuestionAdmin)
|
| 21 |
-
admin.site.register(Choice)
|
|
|
|
|
|
| 1 |
from django.contrib import admin
|
| 2 |
+
from .models import Question,Choice,Vote
|
| 3 |
|
| 4 |
|
| 5 |
class ChoiceInline(admin.TabularInline):
|
| 6 |
+
fields = ['choice_text']
|
| 7 |
+
model = Choice
|
| 8 |
+
extra = 2
|
| 9 |
|
| 10 |
class QuestionAdmin(admin.ModelAdmin):
|
| 11 |
+
# fields=['question_text','pub_date','author']
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
inlines = [ChoiceInline]
|
| 14 |
+
|
| 15 |
+
readonly_fields = ['pub_date']
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
fieldsets = [("question",{"fields":['question_text']}),
|
| 21 |
+
("Meta data",{"fields":['pub_date','author']})]
|
| 22 |
+
|
| 23 |
+
model = Question
|
| 24 |
+
|
| 25 |
+
def get_changeform_initial_data(self, request):
|
| 26 |
+
return {"author": request.user}
|
| 27 |
|
| 28 |
|
| 29 |
# Register your models here.
|
| 30 |
admin.site.register(Question,QuestionAdmin)
|
| 31 |
+
admin.site.register(Choice)
|
| 32 |
+
admin.site.register(Vote)
|
polls/forms.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from django import forms
|
| 2 |
from django.contrib.auth import get_user_model
|
| 3 |
from accounts.forms import UserAdminCreationForm,UserAdminUpdateForm
|
|
|
|
| 4 |
|
| 5 |
User=get_user_model()
|
| 6 |
|
|
@@ -12,3 +13,11 @@ class UserSignupForm(UserAdminCreationForm):
|
|
| 12 |
class UserLoginForm(forms.Form):
|
| 13 |
email = forms.EmailField()
|
| 14 |
password = forms.CharField(widget=forms.PasswordInput)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from django import forms
|
| 2 |
from django.contrib.auth import get_user_model
|
| 3 |
from accounts.forms import UserAdminCreationForm,UserAdminUpdateForm
|
| 4 |
+
from .models import Question
|
| 5 |
|
| 6 |
User=get_user_model()
|
| 7 |
|
|
|
|
| 13 |
class UserLoginForm(forms.Form):
|
| 14 |
email = forms.EmailField()
|
| 15 |
password = forms.CharField(widget=forms.PasswordInput)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class QuestionForm(forms.ModelForm):
|
| 19 |
+
class Meta:
|
| 20 |
+
model=Question
|
| 21 |
+
fields=('question_text','pub_date','author')
|
| 22 |
+
|
| 23 |
+
|
polls/migrations/0002_question_author.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 4.2.3 on 2023-07-27 01:27
|
| 2 |
+
|
| 3 |
+
from django.conf import settings
|
| 4 |
+
from django.db import migrations, models
|
| 5 |
+
import django.db.models.deletion
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class Migration(migrations.Migration):
|
| 9 |
+
|
| 10 |
+
dependencies = [
|
| 11 |
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 12 |
+
('polls', '0001_initial'),
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
operations = [
|
| 16 |
+
migrations.AddField(
|
| 17 |
+
model_name='question',
|
| 18 |
+
name='author',
|
| 19 |
+
field=models.ForeignKey(default='panthrianuj@gmail.com', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
| 20 |
+
preserve_default=False,
|
| 21 |
+
),
|
| 22 |
+
]
|
polls/migrations/0003_remove_choice_votes_votes.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 4.2.3 on 2023-07-28 06:29
|
| 2 |
+
|
| 3 |
+
from django.conf import settings
|
| 4 |
+
from django.db import migrations, models
|
| 5 |
+
import django.db.models.deletion
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class Migration(migrations.Migration):
|
| 9 |
+
|
| 10 |
+
dependencies = [
|
| 11 |
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 12 |
+
('polls', '0002_question_author'),
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
operations = [
|
| 16 |
+
migrations.RemoveField(
|
| 17 |
+
model_name='choice',
|
| 18 |
+
name='votes',
|
| 19 |
+
),
|
| 20 |
+
migrations.CreateModel(
|
| 21 |
+
name='Votes',
|
| 22 |
+
fields=[
|
| 23 |
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
| 24 |
+
('choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.choice')),
|
| 25 |
+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
| 26 |
+
],
|
| 27 |
+
),
|
| 28 |
+
]
|
polls/migrations/0004_rename_votes_vote.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated by Django 4.2.3 on 2023-07-28 06:32
|
| 2 |
+
|
| 3 |
+
from django.conf import settings
|
| 4 |
+
from django.db import migrations
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class Migration(migrations.Migration):
|
| 8 |
+
|
| 9 |
+
dependencies = [
|
| 10 |
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
| 11 |
+
('polls', '0003_remove_choice_votes_votes'),
|
| 12 |
+
]
|
| 13 |
+
|
| 14 |
+
operations = [
|
| 15 |
+
migrations.RenameModel(
|
| 16 |
+
old_name='Votes',
|
| 17 |
+
new_name='Vote',
|
| 18 |
+
),
|
| 19 |
+
]
|
polls/models.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
| 1 |
from django.db import models
|
| 2 |
import datetime
|
| 3 |
from django.utils import timezone
|
|
|
|
| 4 |
|
|
|
|
| 5 |
# Create your models here.
|
| 6 |
class Question(models.Model):
|
| 7 |
|
|
|
|
| 8 |
question_text = models.CharField(max_length=300)
|
| 9 |
pub_date = models.DateTimeField("date published",default=datetime.datetime.now)
|
| 10 |
|
|
@@ -13,7 +16,11 @@ class Question(models.Model):
|
|
| 13 |
|
| 14 |
@property
|
| 15 |
def total_votes(self):
|
| 16 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
def was_recently_pub(self):
|
| 18 |
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
|
| 19 |
|
|
@@ -22,7 +29,19 @@ class Choice(models.Model):
|
|
| 22 |
|
| 23 |
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
| 24 |
choice_text = models.CharField(max_length=200)
|
| 25 |
-
votes = models.IntegerField(default=0)
|
| 26 |
|
| 27 |
def __str__(self):
|
| 28 |
-
return self.question.question_text+"-"*5+self.choice_text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from django.db import models
|
| 2 |
import datetime
|
| 3 |
from django.utils import timezone
|
| 4 |
+
from django.contrib.auth import get_user_model
|
| 5 |
|
| 6 |
+
User=get_user_model()
|
| 7 |
# Create your models here.
|
| 8 |
class Question(models.Model):
|
| 9 |
|
| 10 |
+
author = models.ForeignKey(User,on_delete=models.CASCADE)
|
| 11 |
question_text = models.CharField(max_length=300)
|
| 12 |
pub_date = models.DateTimeField("date published",default=datetime.datetime.now)
|
| 13 |
|
|
|
|
| 16 |
|
| 17 |
@property
|
| 18 |
def total_votes(self):
|
| 19 |
+
return len(Vote.objects.filter(choice__question__pk=self.pk))
|
| 20 |
+
|
| 21 |
+
def has_user_voted(self,user):
|
| 22 |
+
return len(Vote.objects.filter(choice__question__pk=self.pk,user=user))>0
|
| 23 |
+
|
| 24 |
def was_recently_pub(self):
|
| 25 |
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
|
| 26 |
|
|
|
|
| 29 |
|
| 30 |
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
| 31 |
choice_text = models.CharField(max_length=200)
|
|
|
|
| 32 |
|
| 33 |
def __str__(self):
|
| 34 |
+
return self.question.question_text+"-"*5+self.choice_text
|
| 35 |
+
|
| 36 |
+
@property
|
| 37 |
+
def vote_count(self):
|
| 38 |
+
return len(Vote.objects.filter(choice=self.pk))
|
| 39 |
+
@property
|
| 40 |
+
def vote_percent(self):
|
| 41 |
+
return "{:.2f}".format(((self.vote_count/(self.question.total_votes))*100))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class Vote(models.Model):
|
| 46 |
+
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
| 47 |
+
choice = models.ForeignKey(Choice, on_delete=models.CASCADE)
|
polls/static/polls/create.css
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*********************sub header***************************/
|
| 2 |
+
#sub_header{
|
| 3 |
+
font-weight:100;
|
| 4 |
+
padding:40px 40px;
|
| 5 |
+
padding-bottom: 0px;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
/*******************main container*******************************/
|
| 10 |
+
|
| 11 |
+
#main_container{
|
| 12 |
+
display: flex;
|
| 13 |
+
flex-direction: column;
|
| 14 |
+
align-items: center;
|
| 15 |
+
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.question_container{
|
| 19 |
+
width:500px;
|
| 20 |
+
|
| 21 |
+
color:#ffffff;
|
| 22 |
+
background-color: #5B66C6;
|
| 23 |
+
|
| 24 |
+
border-radius: 7px;
|
| 25 |
+
box-shadow: 0px 20px 52px 0px #0000004b;
|
| 26 |
+
overflow: hidden;
|
| 27 |
+
margin-top:40px;
|
| 28 |
+
}
|
| 29 |
+
.question_container:last-child{
|
| 30 |
+
margin-bottom:40px;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.question_header{
|
| 34 |
+
padding: 30px 20px;
|
| 35 |
+
display: flex;
|
| 36 |
+
flex-direction: row;
|
| 37 |
+
align-items: center;
|
| 38 |
+
justify-content: space-between;
|
| 39 |
+
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
.question_meta{
|
| 44 |
+
display: flex;
|
| 45 |
+
flex-direction: column;
|
| 46 |
+
align-items: center;
|
| 47 |
+
justify-content: center;
|
| 48 |
+
margin-right: 30px;
|
| 49 |
+
|
| 50 |
+
font-size: small;
|
| 51 |
+
font-weight: 100;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.question_header>#question_text{
|
| 55 |
+
height: 20px;
|
| 56 |
+
width: 60%;
|
| 57 |
+
color:white;
|
| 58 |
+
background-color: #5B66C6;
|
| 59 |
+
border:none;
|
| 60 |
+
outline: none;
|
| 61 |
+
border-bottom:white solid 2px;
|
| 62 |
+
|
| 63 |
+
display: block;
|
| 64 |
+
overflow: hidden;
|
| 65 |
+
resize: none;
|
| 66 |
+
}
|
| 67 |
+
.question_header>#question_text::placeholder{
|
| 68 |
+
color:#dddbdb;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.question_header>.right_section{
|
| 72 |
+
display: flex;
|
| 73 |
+
align-items: center;
|
| 74 |
+
|
| 75 |
+
}
|
| 76 |
+
.question_header>.right_section>img{
|
| 77 |
+
fill: white;
|
| 78 |
+
height: 25px;
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.question_container>.form_container{
|
| 84 |
+
box-sizing: border-box;
|
| 85 |
+
padding: 10px 20px;
|
| 86 |
+
width: 100%;
|
| 87 |
+
border-radius: 7px;
|
| 88 |
+
|
| 89 |
+
background-color: white;
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
display:flex;
|
| 93 |
+
flex-direction: column;
|
| 94 |
+
align-items: center;
|
| 95 |
+
|
| 96 |
+
}
|
| 97 |
+
.choices{
|
| 98 |
+
margin-top: 30px;
|
| 99 |
+
width: 100%;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.choice{
|
| 103 |
+
margin: 10px 0;
|
| 104 |
+
padding: 10px 20px;
|
| 105 |
+
|
| 106 |
+
background-color: #5b66c670;
|
| 107 |
+
|
| 108 |
+
border-radius: 3px;
|
| 109 |
+
|
| 110 |
+
display: flex;
|
| 111 |
+
position: relative;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.choice_text{
|
| 115 |
+
margin-left: 20px;
|
| 116 |
+
width: 80%;
|
| 117 |
+
|
| 118 |
+
color:white;
|
| 119 |
+
background-color:transparent;
|
| 120 |
+
border:none;
|
| 121 |
+
outline: none;
|
| 122 |
+
border-bottom:white solid 2px;
|
| 123 |
+
|
| 124 |
+
display: block;
|
| 125 |
+
overflow: hidden;
|
| 126 |
+
resize: none;
|
| 127 |
+
}
|
| 128 |
+
.remove_choice_btn{
|
| 129 |
+
position: absolute;
|
| 130 |
+
right:20px;
|
| 131 |
+
color: red;
|
| 132 |
+
/* top:2px; */
|
| 133 |
+
}
|
| 134 |
+
.remove_choice_btn:hover{
|
| 135 |
+
cursor: pointer;
|
| 136 |
+
}
|
| 137 |
+
.create_btn{
|
| 138 |
+
margin: 10px 0;
|
| 139 |
+
border:none;
|
| 140 |
+
outline: none;
|
| 141 |
+
|
| 142 |
+
background-color: #5B66C6;
|
| 143 |
+
color: white;
|
| 144 |
+
padding: 10px 30px;
|
| 145 |
+
border-radius: 8px;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.create_btn:hover{
|
| 149 |
+
cursor: pointer;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
#add_option{
|
| 154 |
+
color:#5B66C6;
|
| 155 |
+
|
| 156 |
+
}
|
| 157 |
+
#add_option:hover{
|
| 158 |
+
text-decoration:#5B66C6 underline solid 2px;
|
| 159 |
+
cursor: pointer;
|
| 160 |
+
}
|
polls/static/polls/create.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
var tx = document.getElementsByTagName('textarea');
|
| 3 |
+
for (var i = 0; i < tx.length; i++) {
|
| 4 |
+
tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
|
| 5 |
+
tx[i].addEventListener("input", OnInput, false);
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
function OnInput(e) {
|
| 9 |
+
e.target.style.height = 'auto';
|
| 10 |
+
e.target.style.height = (e.target.scrollHeight) + 'px';
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
function getCookie(name) {
|
| 15 |
+
let cookieValue = null;
|
| 16 |
+
|
| 17 |
+
if (document.cookie && document.cookie !== '') {
|
| 18 |
+
const cookies = document.cookie.split(';');
|
| 19 |
+
for (let i = 0; i < cookies.length; i++) {
|
| 20 |
+
const cookie = cookies[i].trim();
|
| 21 |
+
|
| 22 |
+
// Does this cookie string begin with the name we want?
|
| 23 |
+
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
| 24 |
+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
| 25 |
+
|
| 26 |
+
break;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
return cookieValue;
|
| 32 |
+
}
|
| 33 |
+
const csrftoken = getCookie('csrftoken');
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
function number_choices(){
|
| 40 |
+
var i=0;
|
| 41 |
+
var choice_list=document.querySelectorAll(".choices>.choice");
|
| 42 |
+
choice_list.forEach(choice=>{
|
| 43 |
+
i++;
|
| 44 |
+
choice.querySelector("span>span").innerHTML=String.fromCharCode(i+64);
|
| 45 |
+
})
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
function create_choice(){
|
| 51 |
+
/*
|
| 52 |
+
<div class="choice">
|
| 53 |
+
<span>
|
| 54 |
+
<span>{{ forloop.counter|add:"64"|stringformat:"c" }}</span>
|
| 55 |
+
<span> -</span>
|
| 56 |
+
</span>
|
| 57 |
+
<span class="choice_text">{{ choice.choice_text }}</span>
|
| 58 |
+
</div>
|
| 59 |
+
*/
|
| 60 |
+
|
| 61 |
+
// <div class="remove_choice_btn" onclick="delete_choice()">X</div>
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
var choices_div=document.querySelector(".choices");
|
| 65 |
+
var choice_div=document.createElement("div");
|
| 66 |
+
choice_div.className="choice";
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
choice_div.innerHTML=`<span>\
|
| 70 |
+
<span>A</span>\
|
| 71 |
+
<span> -</span>\
|
| 72 |
+
</span>\
|
| 73 |
+
<textarea class="choice_text" oninput="OnInput(event)"></textarea>`;
|
| 74 |
+
|
| 75 |
+
if (choices_div.querySelectorAll(".choice").length>0){
|
| 76 |
+
choice_div.innerHTML+=`<div class="remove_choice_btn" onclick="delete_choice(this)">X</div>`;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
choices_div.appendChild(choice_div);
|
| 80 |
+
|
| 81 |
+
number_choices();
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
function delete_choice(elem){
|
| 87 |
+
|
| 88 |
+
elem.parentNode.remove();
|
| 89 |
+
number_choices();
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
function validate(){
|
| 94 |
+
if(question_text.value==''){
|
| 95 |
+
question_text.style.borderBottom="2px solid red";
|
| 96 |
+
question_text.focus();
|
| 97 |
+
|
| 98 |
+
return false;
|
| 99 |
+
}
|
| 100 |
+
else{
|
| 101 |
+
question_text.style.removeProperty("border-bottom");
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
choice_list=document.querySelectorAll(".choice");
|
| 105 |
+
var i=0;
|
| 106 |
+
for(i=0;i<choice_list.length;i++){
|
| 107 |
+
choice_text=choice_list[i].querySelector(".choice_text");
|
| 108 |
+
|
| 109 |
+
if(choice_text.value==""){
|
| 110 |
+
choice_text.style.borderBottom="2px solid red";
|
| 111 |
+
choice_text.focus();
|
| 112 |
+
return false
|
| 113 |
+
}
|
| 114 |
+
else{
|
| 115 |
+
choice_text.style.removeProperty("border-bottom");
|
| 116 |
+
}
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
return true;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
function create_question(){
|
| 125 |
+
if(!validate()) return;
|
| 126 |
+
|
| 127 |
+
var data_to_send = {};
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
var choice_text_list=[];
|
| 133 |
+
choice_list=document.querySelectorAll(".choice");
|
| 134 |
+
var i=0;
|
| 135 |
+
for(i=0;i<choice_list.length;i++){
|
| 136 |
+
choice_text=choice_list[i].querySelector(".choice_text");
|
| 137 |
+
|
| 138 |
+
choice_text_list.push(choice_text.value);
|
| 139 |
+
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
// console.log(question_text.value);
|
| 143 |
+
// console.log(choice_text_list);
|
| 144 |
+
|
| 145 |
+
data_to_send["question_text"]=question_text.value;
|
| 146 |
+
data_to_send["choice_text_list"]=choice_text_list;
|
| 147 |
+
|
| 148 |
+
fetch("",{
|
| 149 |
+
method:"POST",
|
| 150 |
+
headers:{
|
| 151 |
+
'X-CSRFToken': csrftoken
|
| 152 |
+
},
|
| 153 |
+
body:JSON.stringify(data_to_send)
|
| 154 |
+
}).then(res=>res.json()).then(res=>{
|
| 155 |
+
console.log(res);
|
| 156 |
+
if (!res.hasOwnProperty("error_message")){
|
| 157 |
+
window.location.href = res["redirect"];
|
| 158 |
+
}
|
| 159 |
+
});
|
| 160 |
+
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
create_choice();
|
| 164 |
+
create_choice();
|
polls/static/polls/header.css
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*{
|
| 2 |
+
padding:0px;
|
| 3 |
+
margin: 0px;
|
| 4 |
+
}
|
| 5 |
+
header{
|
| 6 |
+
background-color: #5B66C6;
|
| 7 |
+
color:white;
|
| 8 |
+
height:80px;
|
| 9 |
+
display: flex;
|
| 10 |
+
flex-direction: row;
|
| 11 |
+
align-items: center;
|
| 12 |
+
justify-content: space-between;
|
| 13 |
+
padding: 0 80px;
|
| 14 |
+
}
|
| 15 |
+
header>#app_name{
|
| 16 |
+
font-size: larger;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
#profile{
|
| 20 |
+
background-color: #00000058;
|
| 21 |
+
|
| 22 |
+
height: 60px;
|
| 23 |
+
aspect-ratio: 1;
|
| 24 |
+
border-radius: 50%;
|
| 25 |
+
position:relative;
|
| 26 |
+
}
|
| 27 |
+
#profile:hover{
|
| 28 |
+
cursor: pointer;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
#profile>#first_alpha{
|
| 32 |
+
position:absolute;
|
| 33 |
+
top:50%;
|
| 34 |
+
left:50%;
|
| 35 |
+
transform: translate(-50%,-50%);
|
| 36 |
+
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
#profile>#profile_options{
|
| 40 |
+
position: absolute;
|
| 41 |
+
right:0;
|
| 42 |
+
top: 100%;
|
| 43 |
+
margin-top:10px;
|
| 44 |
+
|
| 45 |
+
background-color: #ffffff;
|
| 46 |
+
|
| 47 |
+
width: 180px;
|
| 48 |
+
|
| 49 |
+
box-shadow: 0px 4px 29px 0px #0000004b;
|
| 50 |
+
border-radius: 10px;
|
| 51 |
+
|
| 52 |
+
overflow: hidden;
|
| 53 |
+
}
|
| 54 |
+
#profile_options.hidden{
|
| 55 |
+
display: none;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
#profile_options>.option{
|
| 59 |
+
|
| 60 |
+
padding: 10px 0;
|
| 61 |
+
color:black;
|
| 62 |
+
border-bottom: #C3C3C3 solid 1px;
|
| 63 |
+
text-decoration: none;
|
| 64 |
+
display: flex;
|
| 65 |
+
flex-direction: column;
|
| 66 |
+
align-items: center;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
#profile_options>.option:last-child{
|
| 70 |
+
border-bottom:none; /*used to remove border of last option*/
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
#profile_options>.option:hover{
|
| 74 |
+
background-color: gray;
|
| 75 |
+
color:white;
|
| 76 |
+
}
|
| 77 |
+
|
polls/static/polls/index.css
CHANGED
|
@@ -35,87 +35,13 @@
|
|
| 35 |
|
| 36 |
/***********************New css*****************************/
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
header{
|
| 48 |
-
background-color: #5B66C6;
|
| 49 |
-
color:white;
|
| 50 |
-
height:80px;
|
| 51 |
-
display: flex;
|
| 52 |
-
flex-direction: row;
|
| 53 |
-
align-items: center;
|
| 54 |
-
justify-content: space-between;
|
| 55 |
-
padding: 0 80px;
|
| 56 |
-
}
|
| 57 |
-
header>#app_name{
|
| 58 |
-
font-size: larger;
|
| 59 |
-
}
|
| 60 |
-
|
| 61 |
-
#profile{
|
| 62 |
-
background-color: #00000058;
|
| 63 |
-
|
| 64 |
-
height: 60px;
|
| 65 |
-
aspect-ratio: 1;
|
| 66 |
-
border-radius: 50%;
|
| 67 |
-
position:relative;
|
| 68 |
-
}
|
| 69 |
-
#profile:hover{
|
| 70 |
-
cursor: pointer;
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
-
#profile>#first_alpha{
|
| 74 |
-
position:absolute;
|
| 75 |
-
top:50%;
|
| 76 |
-
left:50%;
|
| 77 |
-
transform: translate(-50%,-50%);
|
| 78 |
-
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
#profile>#profile_options{
|
| 82 |
-
position: absolute;
|
| 83 |
-
right:0;
|
| 84 |
-
top: 100%;
|
| 85 |
-
margin-top:10px;
|
| 86 |
-
|
| 87 |
-
background-color: #ffffff;
|
| 88 |
-
|
| 89 |
-
width: 180px;
|
| 90 |
-
|
| 91 |
-
box-shadow: 0px 4px 29px 0px #0000004b;
|
| 92 |
-
border-radius: 10px;
|
| 93 |
-
|
| 94 |
-
overflow: hidden;
|
| 95 |
-
}
|
| 96 |
-
#profile_options.hidden{
|
| 97 |
-
display: none;
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
#profile_options>.option{
|
| 101 |
-
|
| 102 |
-
padding: 10px 0;
|
| 103 |
-
color:black;
|
| 104 |
-
border-bottom: #C3C3C3 solid 1px;
|
| 105 |
-
|
| 106 |
-
display: flex;
|
| 107 |
-
flex-direction: column;
|
| 108 |
-
align-items: center;
|
| 109 |
}
|
| 110 |
|
| 111 |
-
#profile_options>.option:last-child{
|
| 112 |
-
border-bottom:none; /*used to remove border of last option*/
|
| 113 |
-
}
|
| 114 |
|
| 115 |
-
#profile_options>.option:hover{
|
| 116 |
-
background-color: gray;
|
| 117 |
-
color:white;
|
| 118 |
-
}
|
| 119 |
|
| 120 |
|
| 121 |
|
|
@@ -141,13 +67,16 @@ header>#app_name{
|
|
| 141 |
width:500px;
|
| 142 |
|
| 143 |
color:#ffffff;
|
| 144 |
-
background-color:
|
| 145 |
|
| 146 |
border-radius: 7px;
|
| 147 |
box-shadow: 0px 20px 52px 0px #0000004b;
|
| 148 |
overflow: hidden;
|
| 149 |
margin-top:40px;
|
| 150 |
}
|
|
|
|
|
|
|
|
|
|
| 151 |
|
| 152 |
.question_header{
|
| 153 |
padding: 10px 20px;
|
|
@@ -169,8 +98,15 @@ header>#app_name{
|
|
| 169 |
font-weight: 100;
|
| 170 |
}
|
| 171 |
|
| 172 |
-
.question_header
|
| 173 |
width: 60%;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
}
|
| 175 |
.question_header>.right_section{
|
| 176 |
display: flex;
|
|
@@ -207,27 +143,44 @@ header>#app_name{
|
|
| 207 |
margin: 10px 0;
|
| 208 |
padding: 10px 20px;
|
| 209 |
|
| 210 |
-
background-color:
|
| 211 |
|
| 212 |
border-radius: 3px;
|
|
|
|
| 213 |
}
|
| 214 |
|
| 215 |
.choice_text{
|
| 216 |
margin-left: 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
}
|
| 218 |
|
| 219 |
.choice:hover{
|
| 220 |
-
background-color:
|
| 221 |
/* color:#C3C3C3; */
|
| 222 |
cursor: pointer;
|
| 223 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
.vote_btn{
|
| 226 |
margin: 10px 0;
|
| 227 |
border:none;
|
| 228 |
outline: none;
|
| 229 |
|
| 230 |
-
background-color:
|
| 231 |
color: white;
|
| 232 |
padding: 10px 30px;
|
| 233 |
border-radius: 8px;
|
|
|
|
| 35 |
|
| 36 |
/***********************New css*****************************/
|
| 37 |
|
| 38 |
+
:root{
|
| 39 |
+
--primary-color:#5B66C6;
|
| 40 |
+
--secondary-color:#5b66c670;
|
| 41 |
+
--percentage-color:#7a73ff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
}
|
| 43 |
|
|
|
|
|
|
|
|
|
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
|
| 47 |
|
|
|
|
| 67 |
width:500px;
|
| 68 |
|
| 69 |
color:#ffffff;
|
| 70 |
+
background-color: var(--primary-color);
|
| 71 |
|
| 72 |
border-radius: 7px;
|
| 73 |
box-shadow: 0px 20px 52px 0px #0000004b;
|
| 74 |
overflow: hidden;
|
| 75 |
margin-top:40px;
|
| 76 |
}
|
| 77 |
+
.question_container:last-child{
|
| 78 |
+
margin-bottom:40px;
|
| 79 |
+
}
|
| 80 |
|
| 81 |
.question_header{
|
| 82 |
padding: 10px 20px;
|
|
|
|
| 98 |
font-weight: 100;
|
| 99 |
}
|
| 100 |
|
| 101 |
+
.question_header>.question_text{
|
| 102 |
width: 60%;
|
| 103 |
+
color:white;
|
| 104 |
+
background-color: var(--primary-color);
|
| 105 |
+
border:none;
|
| 106 |
+
outline: none;
|
| 107 |
+
|
| 108 |
+
overflow: hidden;
|
| 109 |
+
resize: none;
|
| 110 |
}
|
| 111 |
.question_header>.right_section{
|
| 112 |
display: flex;
|
|
|
|
| 143 |
margin: 10px 0;
|
| 144 |
padding: 10px 20px;
|
| 145 |
|
| 146 |
+
background-color: var(--secondary-color);
|
| 147 |
|
| 148 |
border-radius: 3px;
|
| 149 |
+
display: flex;
|
| 150 |
}
|
| 151 |
|
| 152 |
.choice_text{
|
| 153 |
margin-left: 20px;
|
| 154 |
+
width: 70%;
|
| 155 |
+
color:white;
|
| 156 |
+
background-color:transparent;
|
| 157 |
+
border:none;
|
| 158 |
+
outline: none;
|
| 159 |
+
overflow: hidden;
|
| 160 |
+
resize: none;
|
| 161 |
+
}
|
| 162 |
+
.choice_text:hover{
|
| 163 |
+
cursor:pointer;
|
| 164 |
}
|
| 165 |
|
| 166 |
.choice:hover{
|
| 167 |
+
background-color: var(--primary-color);
|
| 168 |
/* color:#C3C3C3; */
|
| 169 |
cursor: pointer;
|
| 170 |
}
|
| 171 |
+
.choice.active{
|
| 172 |
+
background-color: var(--primary-color);
|
| 173 |
+
}
|
| 174 |
+
/* .choices.result>.choice{
|
| 175 |
+
background: linear-gradient(90deg, var(--percentage-color) 50%, var(--secondary-color) 0%);
|
| 176 |
+
} */
|
| 177 |
|
| 178 |
.vote_btn{
|
| 179 |
margin: 10px 0;
|
| 180 |
border:none;
|
| 181 |
outline: none;
|
| 182 |
|
| 183 |
+
background-color: var(--primary-color);
|
| 184 |
color: white;
|
| 185 |
padding: 10px 30px;
|
| 186 |
border-radius: 8px;
|
polls/static/polls/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
var tx = document.getElementsByTagName('textarea');
|
| 3 |
+
for (var i = 0; i < tx.length; i++) {
|
| 4 |
+
tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
|
| 5 |
+
tx[i].addEventListener("input", OnInput, false);
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
function OnInput(e) {
|
| 9 |
+
e.target.style.height = 'auto';
|
| 10 |
+
e.target.style.height = (e.target.scrollHeight) + 'px';
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
function getCookie(name) {
|
| 15 |
+
let cookieValue = null;
|
| 16 |
+
|
| 17 |
+
if (document.cookie && document.cookie !== '') {
|
| 18 |
+
const cookies = document.cookie.split(';');
|
| 19 |
+
for (let i = 0; i < cookies.length; i++) {
|
| 20 |
+
const cookie = cookies[i].trim();
|
| 21 |
+
|
| 22 |
+
// Does this cookie string begin with the name we want?
|
| 23 |
+
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
| 24 |
+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
| 25 |
+
|
| 26 |
+
break;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
return cookieValue;
|
| 32 |
+
}
|
| 33 |
+
const csrftoken = getCookie('csrftoken');
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
function select_option(elem){
|
| 40 |
+
elem.parentNode.querySelectorAll(".choice.active").forEach(choice => {
|
| 41 |
+
if (elem!=choice)
|
| 42 |
+
choice.classList.remove("active");
|
| 43 |
+
});
|
| 44 |
+
elem.classList.toggle("active");
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
function validate(elem){
|
| 49 |
+
var active_choices=elem.querySelectorAll(".choice.active");
|
| 50 |
+
for(var i=0;i<active_choices.length;i++){
|
| 51 |
+
return true;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
return false;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
function Vote(elem){
|
| 58 |
+
if(!validate(elem.parentElement)) return;
|
| 59 |
+
|
| 60 |
+
var data_to_send = {};
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
data_to_send["choice_id"]=elem.parentElement.querySelector('.choice.active').dataset.id;
|
| 64 |
+
|
| 65 |
+
fetch("vote/",{
|
| 66 |
+
method:"POST",
|
| 67 |
+
headers:{
|
| 68 |
+
'X-CSRFToken': csrftoken
|
| 69 |
+
},
|
| 70 |
+
body:JSON.stringify(data_to_send)
|
| 71 |
+
}).then(res=>res.json()).then(res=>{
|
| 72 |
+
console.log(res);
|
| 73 |
+
|
| 74 |
+
if (res["message"]=="success"){
|
| 75 |
+
|
| 76 |
+
elem.parentElement.querySelectorAll(".choice").forEach(choice=>{
|
| 77 |
+
choice.dataset.percent=res['vote_percent_dict'][choice.dataset.id];
|
| 78 |
+
show_result(choice);
|
| 79 |
+
});
|
| 80 |
+
// update total vote by adding 1
|
| 81 |
+
var total_votes=elem.parentElement.parentElement.querySelector(".total_votes");
|
| 82 |
+
total_votes.innerText=parseInt(total_votes.innerText)+1;
|
| 83 |
+
console.log(total_votes);
|
| 84 |
+
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
});
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
document.querySelectorAll(".choices.result>.choice").forEach(choice=>{
|
| 93 |
+
console.log(choice.dataset.percent);
|
| 94 |
+
show_result(choice);
|
| 95 |
+
});
|
| 96 |
+
|
| 97 |
+
function show_result(choice){
|
| 98 |
+
choice.style.background= `linear-gradient(90deg, var(--percentage-color) ${choice.dataset.percent}%, var(--secondary-color) 0%)`;
|
| 99 |
+
choice.innerHTML+=choice.dataset.percent+"%";
|
| 100 |
+
}
|
polls/static/polls/your_polls.css
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* .questions{
|
| 2 |
+
display: flex;
|
| 3 |
+
flex-wrap: wrap;
|
| 4 |
+
}
|
| 5 |
+
.question{
|
| 6 |
+
background-color: rgb(133, 127, 255);
|
| 7 |
+
color: white;
|
| 8 |
+
padding: 4px;
|
| 9 |
+
margin:20px 4px;
|
| 10 |
+
width:140px;
|
| 11 |
+
height: 150px;
|
| 12 |
+
border-radius: 10px;
|
| 13 |
+
position:relative;
|
| 14 |
+
}
|
| 15 |
+
.question>.question_text{
|
| 16 |
+
font: caption;
|
| 17 |
+
margin: 0px;
|
| 18 |
+
padding: 0px;
|
| 19 |
+
margin-bottom: 14px;
|
| 20 |
+
}
|
| 21 |
+
.question:hover{
|
| 22 |
+
cursor: pointer;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.total_count{
|
| 26 |
+
font:-webkit-control;
|
| 27 |
+
color: black;
|
| 28 |
+
position:absolute;
|
| 29 |
+
bottom: 5px;
|
| 30 |
+
right: 5px;
|
| 31 |
+
padding: 0;
|
| 32 |
+
margin: 0;
|
| 33 |
+
} */
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
/***********************New css*****************************/
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
/*********************sub header***************************/
|
| 46 |
+
#sub_header{
|
| 47 |
+
font-weight:100;
|
| 48 |
+
padding:40px 40px;
|
| 49 |
+
padding-bottom: 0px;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
/*******************main container*******************************/
|
| 54 |
+
|
| 55 |
+
#main_container{
|
| 56 |
+
display: flex;
|
| 57 |
+
flex-direction: column;
|
| 58 |
+
align-items: center;
|
| 59 |
+
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.question_container{
|
| 63 |
+
width:500px;
|
| 64 |
+
|
| 65 |
+
color:#ffffff;
|
| 66 |
+
background-color: #5B66C6;
|
| 67 |
+
|
| 68 |
+
border-radius: 7px;
|
| 69 |
+
box-shadow: 0px 20px 52px 0px #0000004b;
|
| 70 |
+
overflow: hidden;
|
| 71 |
+
margin-top:40px;
|
| 72 |
+
}
|
| 73 |
+
.question_container:last-child{
|
| 74 |
+
margin-bottom:40px;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.question_header{
|
| 78 |
+
padding: 10px 20px;
|
| 79 |
+
display: flex;
|
| 80 |
+
flex-direction: row;
|
| 81 |
+
align-items: center;
|
| 82 |
+
justify-content: space-between;
|
| 83 |
+
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.question_meta{
|
| 87 |
+
display: flex;
|
| 88 |
+
flex-direction: column;
|
| 89 |
+
align-items: center;
|
| 90 |
+
justify-content: center;
|
| 91 |
+
margin-right: 30px;
|
| 92 |
+
|
| 93 |
+
font-size: small;
|
| 94 |
+
font-weight: 100;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.question_header>.question_text{
|
| 98 |
+
width: 60%;
|
| 99 |
+
color:white;
|
| 100 |
+
background-color: #5B66C6;
|
| 101 |
+
border:none;
|
| 102 |
+
outline: none;
|
| 103 |
+
|
| 104 |
+
overflow: hidden;
|
| 105 |
+
resize: none;
|
| 106 |
+
}
|
| 107 |
+
.question_header>.right_section{
|
| 108 |
+
display: flex;
|
| 109 |
+
align-items: center;
|
| 110 |
+
|
| 111 |
+
}
|
| 112 |
+
.question_header>.right_section>img{
|
| 113 |
+
fill: white;
|
| 114 |
+
height: 25px;
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.question_container>.form_container{
|
| 120 |
+
box-sizing: border-box;
|
| 121 |
+
padding: 10px 20px;
|
| 122 |
+
width: 100%;
|
| 123 |
+
border-radius: 7px;
|
| 124 |
+
|
| 125 |
+
background-color: white;
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
display:flex;
|
| 129 |
+
flex-direction: column;
|
| 130 |
+
align-items: center;
|
| 131 |
+
|
| 132 |
+
}
|
| 133 |
+
.choices{
|
| 134 |
+
margin-top: 30px;
|
| 135 |
+
width: 100%;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.choice{
|
| 139 |
+
margin: 10px 0;
|
| 140 |
+
padding: 10px 20px;
|
| 141 |
+
|
| 142 |
+
background-color: #5b66c670;
|
| 143 |
+
|
| 144 |
+
border-radius: 3px;
|
| 145 |
+
display: flex;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.choice_text{
|
| 149 |
+
margin-left: 20px;
|
| 150 |
+
color:white;
|
| 151 |
+
background-color:transparent;
|
| 152 |
+
border:none;
|
| 153 |
+
outline: none;
|
| 154 |
+
overflow: hidden;
|
| 155 |
+
resize: none;
|
| 156 |
+
}
|
| 157 |
+
.choice_text:hover{
|
| 158 |
+
cursor:pointer;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.choice:hover{
|
| 162 |
+
background-color: #5B66C6;
|
| 163 |
+
/* color:#C3C3C3; */
|
| 164 |
+
cursor: pointer;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.vote_btn{
|
| 168 |
+
margin: 10px 0;
|
| 169 |
+
border:none;
|
| 170 |
+
outline: none;
|
| 171 |
+
|
| 172 |
+
background-color: #5B66C6;
|
| 173 |
+
color: white;
|
| 174 |
+
padding: 10px 30px;
|
| 175 |
+
border-radius: 8px;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
.vote_btn:hover{
|
| 179 |
+
cursor: pointer;
|
| 180 |
+
}
|
polls/static/polls/your_polls.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
var tx = document.getElementsByTagName('textarea');
|
| 3 |
+
for (var i = 0; i < tx.length; i++) {
|
| 4 |
+
tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
|
| 5 |
+
tx[i].addEventListener("input", OnInput, false);
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
function OnInput(e) {
|
| 9 |
+
e.target.style.height = 'auto';
|
| 10 |
+
e.target.style.height = (e.target.scrollHeight) + 'px';
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
function getCookie(name) {
|
| 15 |
+
let cookieValue = null;
|
| 16 |
+
|
| 17 |
+
if (document.cookie && document.cookie !== '') {
|
| 18 |
+
const cookies = document.cookie.split(';');
|
| 19 |
+
for (let i = 0; i < cookies.length; i++) {
|
| 20 |
+
const cookie = cookies[i].trim();
|
| 21 |
+
|
| 22 |
+
// Does this cookie string begin with the name we want?
|
| 23 |
+
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
| 24 |
+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
| 25 |
+
|
| 26 |
+
break;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
return cookieValue;
|
| 32 |
+
}
|
| 33 |
+
const csrftoken = getCookie('csrftoken');
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
function validate(){
|
| 38 |
+
if(question_text.value==''){
|
| 39 |
+
question_text.style.borderBottom="2px solid red";
|
| 40 |
+
question_text.focus();
|
| 41 |
+
|
| 42 |
+
return false;
|
| 43 |
+
}
|
| 44 |
+
else{
|
| 45 |
+
question_text.style.removeProperty("border-bottom");
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
choice_list=document.querySelectorAll(".choice");
|
| 49 |
+
var i=0;
|
| 50 |
+
for(i=0;i<choice_list.length;i++){
|
| 51 |
+
choice_text=choice_list[i].querySelector(".choice_text");
|
| 52 |
+
|
| 53 |
+
if(choice_text.value==""){
|
| 54 |
+
choice_text.style.borderBottom="2px solid red";
|
| 55 |
+
choice_text.focus();
|
| 56 |
+
return false
|
| 57 |
+
}
|
| 58 |
+
else{
|
| 59 |
+
choice_text.style.removeProperty("border-bottom");
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
return true;
|
| 64 |
+
}
|
polls/templates/polls/base.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<html>
|
| 2 |
+
<head>
|
| 3 |
+
{% load static %}
|
| 4 |
+
<link type="text/css" rel="stylesheet" href="{% static 'polls/header.css' %}">
|
| 5 |
+
{% include 'polls/font.html' %}
|
| 6 |
+
|
| 7 |
+
{% block head %}{% endblock %}
|
| 8 |
+
|
| 9 |
+
</head>
|
| 10 |
+
<body>
|
| 11 |
+
{% include 'polls/header.html' %}
|
| 12 |
+
|
| 13 |
+
{% block body %}{% endblock %}
|
| 14 |
+
<script src="{% static 'polls/header.js' %}"></script>
|
| 15 |
+
</body>
|
| 16 |
+
</html>
|
polls/templates/polls/create.html
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'polls/base.html' %}
|
| 2 |
+
|
| 3 |
+
{% block head %}
|
| 4 |
+
{% load static %}
|
| 5 |
+
<link type="text/css" rel="stylesheet" href="{% static 'polls/create.css' %}">
|
| 6 |
+
{% endblock %}
|
| 7 |
+
|
| 8 |
+
{% block body %}
|
| 9 |
+
|
| 10 |
+
<h2 id="sub_header">Create Poll</h2>
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
<div id="main_container">
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
<div class="question_container">
|
| 19 |
+
<div class="question_header">
|
| 20 |
+
<textarea id="question_text" placeholder="New question"></textarea>
|
| 21 |
+
|
| 22 |
+
</div>
|
| 23 |
+
<div class="form_container">
|
| 24 |
+
<div class="choices">
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
</div>
|
| 28 |
+
<span id="add_option" onclick="create_choice()">Add option</span>
|
| 29 |
+
<button class="create_btn" onclick="create_question()">Create</button>
|
| 30 |
+
|
| 31 |
+
</div>
|
| 32 |
+
</div>
|
| 33 |
+
|
| 34 |
+
</div>
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
<!-- {% if latest_questions_list %}
|
| 38 |
+
|
| 39 |
+
<div class="questions" >
|
| 40 |
+
{% for question in latest_questions_list %}
|
| 41 |
+
|
| 42 |
+
<div class="question" onclick="window.location.href = `{% url 'polls:detail' question.id %}`;">
|
| 43 |
+
<p class="question_text">{{ question }}</p>
|
| 44 |
+
<p class="total_count">Votes:{{ question.total_votes }}</p>
|
| 45 |
+
</div>
|
| 46 |
+
{% endfor %}
|
| 47 |
+
</div>
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
{% else %}
|
| 51 |
+
<p>No questions yet</p>
|
| 52 |
+
{% endif %} -->
|
| 53 |
+
<script src="{% static 'polls/create.js' %}"></script>
|
| 54 |
+
|
| 55 |
+
{% endblock %}
|
polls/templates/polls/header.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<header>
|
| 2 |
+
<span id="app_name">Polling App</span>
|
| 3 |
+
|
| 4 |
+
<div id="profile" onclick="toggle_profile_options(event)">
|
| 5 |
+
<span id="first_alpha">{{ request.user }}</span>
|
| 6 |
+
|
| 7 |
+
<div id="profile_options" class="hidden">
|
| 8 |
+
<a class="option" href="{% url 'polls:create' %}">Create Poll</a>
|
| 9 |
+
<a class="option" href="{% url 'polls:your_polls' %}">Your Polls</a>
|
| 10 |
+
<a class="option" href = "{% url 'polls:your_votes' %}">Your Votes</a>
|
| 11 |
+
<a class="option" href = "{% url 'polls:settings' %}">Settings</a>
|
| 12 |
+
<a class="option" href = "{% url 'polls:logout' %}">Log Out</a>
|
| 13 |
+
</div>
|
| 14 |
+
|
| 15 |
+
</div>
|
| 16 |
+
</header>
|
polls/templates/polls/index.html
CHANGED
|
@@ -1,26 +1,12 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
| 3 |
{% load static %}
|
| 4 |
<link type="text/css" rel="stylesheet" href="{% static 'polls/index.css' %}">
|
| 5 |
-
|
| 6 |
-
</head>
|
| 7 |
-
<body>
|
| 8 |
-
<header>
|
| 9 |
-
<span id="app_name">Polling App</span>
|
| 10 |
-
|
| 11 |
-
<div id="profile" onclick="toggle_profile_options(event)">
|
| 12 |
-
<span id="first_alpha">{{ request.user }}</span>
|
| 13 |
-
|
| 14 |
-
<div id="profile_options" class="hidden">
|
| 15 |
-
<div class="option">Create Poll</div>
|
| 16 |
-
<div class="option">Your Polls</div>
|
| 17 |
-
<div class="option">Your Votes</div>
|
| 18 |
-
<div class="option">Settings</div>
|
| 19 |
-
<div class="option">Log Out</div>
|
| 20 |
-
</div>
|
| 21 |
|
| 22 |
-
|
| 23 |
-
</header>
|
| 24 |
|
| 25 |
<h2 id="sub_header">Public Polls</h2>
|
| 26 |
|
|
@@ -32,11 +18,11 @@
|
|
| 32 |
|
| 33 |
<div class="question_container">
|
| 34 |
<div class="question_header">
|
| 35 |
-
<
|
| 36 |
<div class="right_section">
|
| 37 |
<div class="question_meta">
|
| 38 |
<span>
|
| 39 |
-
<span>{{ question.total_votes }}</span>
|
| 40 |
Votes
|
| 41 |
</span>
|
| 42 |
|
|
@@ -50,19 +36,26 @@
|
|
| 50 |
</div>
|
| 51 |
</div>
|
| 52 |
<div class="form_container">
|
| 53 |
-
<div class="choices">
|
| 54 |
|
| 55 |
{% for choice in question.choice_set.all %}
|
| 56 |
-
<div class="choice"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
<span>
|
| 58 |
<span>{{ forloop.counter|add:"64"|stringformat:"c" }}</span>
|
| 59 |
<span> -</span>
|
| 60 |
</span>
|
| 61 |
-
<
|
|
|
|
|
|
|
| 62 |
</div>
|
| 63 |
{% endfor %}
|
| 64 |
</div>
|
| 65 |
-
<button class="vote_btn">Vote</button>
|
| 66 |
|
| 67 |
</div>
|
| 68 |
</div>
|
|
@@ -89,6 +82,5 @@
|
|
| 89 |
{% else %}
|
| 90 |
<p>No questions yet</p>
|
| 91 |
{% endif %} -->
|
| 92 |
-
<script src="{% static 'polls/
|
| 93 |
-
|
| 94 |
-
</html>
|
|
|
|
| 1 |
+
{% extends 'polls/base.html' %}
|
| 2 |
+
|
| 3 |
+
{% block head %}
|
| 4 |
+
{% load index %}
|
| 5 |
{% load static %}
|
| 6 |
<link type="text/css" rel="stylesheet" href="{% static 'polls/index.css' %}">
|
| 7 |
+
{% endblock %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
+
{% block body %}
|
|
|
|
| 10 |
|
| 11 |
<h2 id="sub_header">Public Polls</h2>
|
| 12 |
|
|
|
|
| 18 |
|
| 19 |
<div class="question_container">
|
| 20 |
<div class="question_header">
|
| 21 |
+
<textarea oninput="OnInput(event)" class="question_text" readonly="true">{{ question.question_text }}</textarea>
|
| 22 |
<div class="right_section">
|
| 23 |
<div class="question_meta">
|
| 24 |
<span>
|
| 25 |
+
<span class="total_votes">{{ question.total_votes }}</span>
|
| 26 |
Votes
|
| 27 |
</span>
|
| 28 |
|
|
|
|
| 36 |
</div>
|
| 37 |
</div>
|
| 38 |
<div class="form_container">
|
| 39 |
+
<div class="choices {{ question.has_voted|yesno:'result,' }}">
|
| 40 |
|
| 41 |
{% for choice in question.choice_set.all %}
|
| 42 |
+
<div class="choice" onclick="select_option(this)" data-id="{{ choice.pk }}"
|
| 43 |
+
{% if question.has_voted %}
|
| 44 |
+
data-percent="{{ choice.vote_percent }}"
|
| 45 |
+
{% endif %}
|
| 46 |
+
>
|
| 47 |
+
|
| 48 |
<span>
|
| 49 |
<span>{{ forloop.counter|add:"64"|stringformat:"c" }}</span>
|
| 50 |
<span> -</span>
|
| 51 |
</span>
|
| 52 |
+
<textarea class="choice_text" oninput="OnInput(event)" readonly="true">{{ choice.choice_text }}</textarea>
|
| 53 |
+
|
| 54 |
+
|
| 55 |
</div>
|
| 56 |
{% endfor %}
|
| 57 |
</div>
|
| 58 |
+
<button class="vote_btn" onclick="Vote(this)">Vote</button>
|
| 59 |
|
| 60 |
</div>
|
| 61 |
</div>
|
|
|
|
| 82 |
{% else %}
|
| 83 |
<p>No questions yet</p>
|
| 84 |
{% endif %} -->
|
| 85 |
+
<script src="{% static 'polls/index.js' %}"></script>
|
| 86 |
+
{% endblock %}
|
|
|
polls/templates/polls/your_polls.html
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'polls/base.html' %}
|
| 2 |
+
|
| 3 |
+
{% block head %}
|
| 4 |
+
{% load static %}
|
| 5 |
+
<link type="text/css" rel="stylesheet" href="{% static 'polls/index.css' %}">
|
| 6 |
+
{% endblock %}
|
| 7 |
+
|
| 8 |
+
{% block body %}
|
| 9 |
+
|
| 10 |
+
<h2 id="sub_header">Your Polls</h2>
|
| 11 |
+
|
| 12 |
+
{% if latest_questions_list %}
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
<div id="main_container">
|
| 16 |
+
{% for question in latest_questions_list %}
|
| 17 |
+
|
| 18 |
+
<div class="question_container">
|
| 19 |
+
<div class="question_header">
|
| 20 |
+
<textarea oninput="OnInput(event)" class="question_text" readonly="true">{{ question.question_text }}</textarea>
|
| 21 |
+
<div class="right_section">
|
| 22 |
+
<div class="question_meta">
|
| 23 |
+
<span>
|
| 24 |
+
<span>{{ question.total_votes }}</span>
|
| 25 |
+
Votes
|
| 26 |
+
</span>
|
| 27 |
+
|
| 28 |
+
<span>Results in
|
| 29 |
+
<span>1 hour</span>
|
| 30 |
+
</span>
|
| 31 |
+
</div>
|
| 32 |
+
|
| 33 |
+
<img src="{% static 'polls/arrow-up-right-from-square-solid.svg' %}">
|
| 34 |
+
|
| 35 |
+
</div>
|
| 36 |
+
</div>
|
| 37 |
+
<div class="form_container">
|
| 38 |
+
<div class="choices">
|
| 39 |
+
|
| 40 |
+
{% for choice in question.choice_set.all %}
|
| 41 |
+
<div class="choice">
|
| 42 |
+
<span>
|
| 43 |
+
<span>{{ forloop.counter|add:"64"|stringformat:"c" }}</span>
|
| 44 |
+
<span> -</span>
|
| 45 |
+
</span>
|
| 46 |
+
<textarea class="choice_text" oninput="OnInput(event)" readonly="true">{{ choice.choice_text }}</textarea>
|
| 47 |
+
</div>
|
| 48 |
+
{% endfor %}
|
| 49 |
+
</div>
|
| 50 |
+
<button class="vote_btn">Vote</button>
|
| 51 |
+
|
| 52 |
+
</div>
|
| 53 |
+
</div>
|
| 54 |
+
{% endfor %}
|
| 55 |
+
</div>
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
{% else %}
|
| 59 |
+
<p>No questions yet</p>
|
| 60 |
+
{% endif %}
|
| 61 |
+
<!-- {% if latest_questions_list %}
|
| 62 |
+
|
| 63 |
+
<div class="questions" >
|
| 64 |
+
{% for question in latest_questions_list %}
|
| 65 |
+
|
| 66 |
+
<div class="question" onclick="window.location.href = `{% url 'polls:detail' question.id %}`;">
|
| 67 |
+
<p class="question_text">{{ question }}</p>
|
| 68 |
+
<p class="total_count">Votes:{{ question.total_votes }}</p>
|
| 69 |
+
</div>
|
| 70 |
+
{% endfor %}
|
| 71 |
+
</div>
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
{% else %}
|
| 75 |
+
<p>No questions yet</p>
|
| 76 |
+
{% endif %} -->
|
| 77 |
+
<script src="{% static 'polls/index.js' %}"></script>
|
| 78 |
+
{% endblock %}
|
polls/templatetags/__init__.py
ADDED
|
File without changes
|
polls/templatetags/index.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django import template
|
| 2 |
+
|
| 3 |
+
register=template.Library()
|
| 4 |
+
|
| 5 |
+
@register.filter
|
| 6 |
+
def index(indexable,i):
|
| 7 |
+
return indexable[i]
|
polls/urls.py
CHANGED
|
@@ -8,6 +8,13 @@ urlpatterns = [
|
|
| 8 |
path("signup/",views.signup,name="signup"),
|
| 9 |
path("login/",views.login,name="login"),
|
| 10 |
path("details/<int:question_id>/",views.detail,name="detail"),
|
| 11 |
-
path("vote
|
| 12 |
path("result/<int:question_id>/",views.result,name="result"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
]
|
|
|
|
| 8 |
path("signup/",views.signup,name="signup"),
|
| 9 |
path("login/",views.login,name="login"),
|
| 10 |
path("details/<int:question_id>/",views.detail,name="detail"),
|
| 11 |
+
path("vote/",views.vote,name="vote"),
|
| 12 |
path("result/<int:question_id>/",views.result,name="result"),
|
| 13 |
+
|
| 14 |
+
path("create/",views.create,name="create"),
|
| 15 |
+
path("your_polls/",views.your_polls,name="your_polls"),
|
| 16 |
+
path("votes/",views.your_votes,name="your_votes"),
|
| 17 |
+
path("settings/",views.settings,name="settings"),
|
| 18 |
+
path("logout/",views.logout,name="logout"),
|
| 19 |
+
|
| 20 |
]
|
polls/views.py
CHANGED
|
@@ -4,7 +4,7 @@ from django.contrib.auth import login as auth_login,logout as auth_logout
|
|
| 4 |
from django.contrib.auth import get_user_model
|
| 5 |
from django.urls import reverse
|
| 6 |
import json
|
| 7 |
-
from .models import Question,Choice
|
| 8 |
from .forms import UserSignupForm,UserLoginForm
|
| 9 |
|
| 10 |
|
|
@@ -13,7 +13,17 @@ User = get_user_model() # user model
|
|
| 13 |
# Create your views here.
|
| 14 |
def index(request):
|
| 15 |
latest_questions_list = Question.objects.order_by("-pub_date")[:5]
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
return render(request,"polls/index.html",context)
|
| 18 |
|
| 19 |
def detail(request,question_id):
|
|
@@ -24,29 +34,36 @@ def detail(request,question_id):
|
|
| 24 |
|
| 25 |
return render(request,"polls/detail.html",{"question":question})
|
| 26 |
|
| 27 |
-
def vote(request
|
| 28 |
-
|
| 29 |
-
question=get_object_or_404(Question,pk=question_id)
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
try:
|
| 33 |
json_data=json.loads(request.body)
|
| 34 |
print(json_data)
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
selected_choice.save()
|
| 46 |
-
# return HttpResponseRedirect(reverse("polls:result",args=(question_id,)))
|
| 47 |
-
return JsonResponse({
|
| 48 |
-
"redirect":reverse("polls:result",args=(question_id,)),
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
})
|
| 51 |
|
| 52 |
|
|
@@ -117,4 +134,37 @@ def login(request):
|
|
| 117 |
'data':data}
|
| 118 |
# print(context)
|
| 119 |
|
| 120 |
-
return render(request,"polls/login.html",context)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
from django.contrib.auth import get_user_model
|
| 5 |
from django.urls import reverse
|
| 6 |
import json
|
| 7 |
+
from .models import Question,Choice,Vote
|
| 8 |
from .forms import UserSignupForm,UserLoginForm
|
| 9 |
|
| 10 |
|
|
|
|
| 13 |
# Create your views here.
|
| 14 |
def index(request):
|
| 15 |
latest_questions_list = Question.objects.order_by("-pub_date")[:5]
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
for q in latest_questions_list:
|
| 19 |
+
q.has_voted=q.has_user_voted(request.user)
|
| 20 |
+
|
| 21 |
+
# print(latest_questions_list[0].has_voted)
|
| 22 |
+
|
| 23 |
+
context={"latest_questions_list":latest_questions_list,
|
| 24 |
+
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
return render(request,"polls/index.html",context)
|
| 28 |
|
| 29 |
def detail(request,question_id):
|
|
|
|
| 34 |
|
| 35 |
return render(request,"polls/detail.html",{"question":question})
|
| 36 |
|
| 37 |
+
def vote(request):
|
| 38 |
+
if request.method=='POST':
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
json_data=json.loads(request.body)
|
| 40 |
print(json_data)
|
| 41 |
+
choice=get_object_or_404(Choice,pk=json_data['choice_id'])
|
| 42 |
+
# check if already has voted on this question
|
| 43 |
+
|
| 44 |
+
old_vote_on_same_question=Vote.objects.filter(user=request.user,choice__question=choice.question)
|
| 45 |
+
|
| 46 |
+
if len(old_vote_on_same_question)>0:
|
| 47 |
+
return JsonResponse({
|
| 48 |
+
"message":"error",
|
| 49 |
+
'error_message':"you have already voted !"
|
| 50 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
+
|
| 53 |
+
vote=Vote.objects.create(choice=choice,user=request.user)
|
| 54 |
+
vote.save()
|
| 55 |
+
|
| 56 |
+
# get percentage of each choice for showing result
|
| 57 |
+
|
| 58 |
+
vote_percent_dict={c.pk:c.vote_percent for c in choice.question.choice_set.all()}
|
| 59 |
+
|
| 60 |
+
# print(vote_percent_dict)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
return JsonResponse({
|
| 65 |
+
"message":"success",
|
| 66 |
+
"vote_percent_dict" :vote_percent_dict,
|
| 67 |
})
|
| 68 |
|
| 69 |
|
|
|
|
| 134 |
'data':data}
|
| 135 |
# print(context)
|
| 136 |
|
| 137 |
+
return render(request,"polls/login.html",context)
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def create(request):
|
| 141 |
+
if request.method=="GET":
|
| 142 |
+
return render(request,'polls/create.html',{})
|
| 143 |
+
|
| 144 |
+
json_data=json.loads(request.body)
|
| 145 |
+
print(json_data)
|
| 146 |
+
question=Question.objects.create(author=request.user,
|
| 147 |
+
question_text=json_data['question_text'])
|
| 148 |
+
question.save()
|
| 149 |
+
|
| 150 |
+
for choice_text in json_data['choice_text_list']:
|
| 151 |
+
choice=Choice.objects.create(question=question,choice_text=choice_text)
|
| 152 |
+
choice.save()
|
| 153 |
+
|
| 154 |
+
return JsonResponse({
|
| 155 |
+
|
| 156 |
+
"redirect":reverse("polls:index")
|
| 157 |
+
})
|
| 158 |
+
|
| 159 |
+
def your_polls(request):
|
| 160 |
+
latest_questions_list = Question.objects.filter(author=request.user).order_by("-pub_date")[:5]
|
| 161 |
+
context={"latest_questions_list":latest_questions_list}
|
| 162 |
+
return render(request,'polls/your_polls.html',context)
|
| 163 |
+
|
| 164 |
+
def your_votes(request):
|
| 165 |
+
pass
|
| 166 |
+
def settings(request):
|
| 167 |
+
pass
|
| 168 |
+
def logout(request):
|
| 169 |
+
auth_logout(request)
|
| 170 |
+
return HttpResponseRedirect(reverse('polls:login'))
|