mirror of
https://github.com/Sosokker/ku-polls.git
synced 2025-12-18 21:14:05 +01:00
Merge pull request #40 from Sosokker/iteration3
Iteration3 Add Trending and more Test + Modify view to return context about trend and update new poll + user data
This commit is contained in:
commit
30bf6a9341
480
data/polls.json
480
data/polls.json
@ -6,8 +6,9 @@
|
|||||||
"question_text": "Python vs C++, which one is better in your opinion?",
|
"question_text": "Python vs C++, which one is better in your opinion?",
|
||||||
"pub_date": "2023-09-11T06:31:14Z",
|
"pub_date": "2023-09-11T06:31:14Z",
|
||||||
"end_date": "2023-09-29T20:31:49Z",
|
"end_date": "2023-09-29T20:31:49Z",
|
||||||
"short_description": "Cool kids have polls",
|
"short_description": "🐍 vs 🇨 ++",
|
||||||
"long_description": "No description provide for this poll.",
|
"long_description": "Let them fight.",
|
||||||
|
"trend_score": 60.0,
|
||||||
"tags": []
|
"tags": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -18,8 +19,9 @@
|
|||||||
"question_text": "The chicken and the egg, which came first?",
|
"question_text": "The chicken and the egg, which came first?",
|
||||||
"pub_date": "2023-09-11T02:50:04Z",
|
"pub_date": "2023-09-11T02:50:04Z",
|
||||||
"end_date": "2023-10-18T23:50:19Z",
|
"end_date": "2023-10-18T23:50:19Z",
|
||||||
"short_description": "Cool kids have polls",
|
"short_description": "Classic question.",
|
||||||
"long_description": "No description provide for this poll.",
|
"long_description": "Most biologists state unequivocally that the egg came first. At their most basic level, eggs are just female sex cells. Hard external eggs that can be laid on land (also known as amniotic eggs) were a game changer for vertebrates. Anyway, let select you choice.",
|
||||||
|
"trend_score": 140.0,
|
||||||
"tags": []
|
"tags": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -30,8 +32,9 @@
|
|||||||
"question_text": "So far so good?",
|
"question_text": "So far so good?",
|
||||||
"pub_date": "2023-08-03T06:50:43Z",
|
"pub_date": "2023-08-03T06:50:43Z",
|
||||||
"end_date": "2023-11-28T19:50:53Z",
|
"end_date": "2023-11-28T19:50:53Z",
|
||||||
"short_description": "Cool kids have polls",
|
"short_description": "If you know, you know.",
|
||||||
"long_description": "No description provide for this poll.",
|
"long_description": "The sentence where you will hear once every week.",
|
||||||
|
"trend_score": 120.0,
|
||||||
"tags": []
|
"tags": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -42,8 +45,61 @@
|
|||||||
"question_text": "Do you love Django?",
|
"question_text": "Do you love Django?",
|
||||||
"pub_date": "2023-09-11T19:51:12Z",
|
"pub_date": "2023-09-11T19:51:12Z",
|
||||||
"end_date": "2023-09-29T17:51:18Z",
|
"end_date": "2023-09-29T17:51:18Z",
|
||||||
"short_description": "Cool kids have polls",
|
"short_description": "Djago, I love it!",
|
||||||
"long_description": "No description provide for this poll.",
|
"long_description": "Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.",
|
||||||
|
"trend_score": 120.0,
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.question",
|
||||||
|
"pk": 6,
|
||||||
|
"fields": {
|
||||||
|
"question_text": "Taylor Swift vs Kanye West. Who is better!",
|
||||||
|
"pub_date": "2023-09-15T15:46:58Z",
|
||||||
|
"end_date": "2023-11-30T15:47:01Z",
|
||||||
|
"short_description": "Swifty vs Ye Club",
|
||||||
|
"long_description": "It's no secret that Taylor Swift and Kanye West's relationship can be described as volatile at best. Let choose!",
|
||||||
|
"trend_score": 100.0,
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.question",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"question_text": "What is your preferred text editor or IDE for coding?",
|
||||||
|
"pub_date": "2023-09-15T15:49:22Z",
|
||||||
|
"end_date": "2023-11-21T23:00:00Z",
|
||||||
|
"short_description": "Please do my poll🥺",
|
||||||
|
"long_description": "My favorite code editor is VScode. What about you?",
|
||||||
|
"trend_score": 100.0,
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.question",
|
||||||
|
"pk": 8,
|
||||||
|
"fields": {
|
||||||
|
"question_text": "Which one is the best RIZZ line?",
|
||||||
|
"pub_date": "2023-09-14T15:52:03Z",
|
||||||
|
"end_date": "2023-11-14T17:00:00Z",
|
||||||
|
"short_description": "RIZZ (noun) How good you are with flirting",
|
||||||
|
"long_description": "Rizz actually comes from the word charisma. It's a NYC Slang created by a twitch streamer named Kai cenat. This means that you have game, a good flirt line.",
|
||||||
|
"trend_score": 100.0,
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.question",
|
||||||
|
"pk": 9,
|
||||||
|
"fields": {
|
||||||
|
"question_text": "What is the best pizza topping?",
|
||||||
|
"pub_date": "2023-09-15T16:10:02Z",
|
||||||
|
"end_date": "2023-12-31T05:00:00Z",
|
||||||
|
"short_description": "Pizza without topping is not pizza!",
|
||||||
|
"long_description": "I mean, Yeah here are the choices ;)",
|
||||||
|
"trend_score": 100.0,
|
||||||
"tags": []
|
"tags": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -119,6 +175,198 @@
|
|||||||
"choice_text": "No comment."
|
"choice_text": "No comment."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 10,
|
||||||
|
"fields": {
|
||||||
|
"question": 6,
|
||||||
|
"choice_text": "Kanye"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 11,
|
||||||
|
"fields": {
|
||||||
|
"question": 6,
|
||||||
|
"choice_text": "Taylor Swift"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 12,
|
||||||
|
"fields": {
|
||||||
|
"question": 6,
|
||||||
|
"choice_text": "Neither"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 13,
|
||||||
|
"fields": {
|
||||||
|
"question": 6,
|
||||||
|
"choice_text": "Both!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 14,
|
||||||
|
"fields": {
|
||||||
|
"question": 6,
|
||||||
|
"choice_text": "No Opinion"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 15,
|
||||||
|
"fields": {
|
||||||
|
"question": 7,
|
||||||
|
"choice_text": "VScode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 16,
|
||||||
|
"fields": {
|
||||||
|
"question": 7,
|
||||||
|
"choice_text": "IntelliJ IDEA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 17,
|
||||||
|
"fields": {
|
||||||
|
"question": 7,
|
||||||
|
"choice_text": "Vim"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 18,
|
||||||
|
"fields": {
|
||||||
|
"question": 7,
|
||||||
|
"choice_text": "Emacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 19,
|
||||||
|
"fields": {
|
||||||
|
"question": 7,
|
||||||
|
"choice_text": "Eclipse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 20,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Let me be your CSS to your HTML"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 21,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Are you my grade? Because Im nervous everytime Im about to see you"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 22,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "If being beautiful was a crime, you’d be on the most wanted list."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 23,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "You look like mom! Mom of our son."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 24,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Are you from Tennessee cuz u the only ten I see"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 25,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Ouch i skinned my knee! because I fall for you"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 26,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Are you semicolon!! cause you alway make me complete."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 27,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "Roses are red, Violets are blue, Something smells is that you!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 28,
|
||||||
|
"fields": {
|
||||||
|
"question": 9,
|
||||||
|
"choice_text": "Pineapples"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 29,
|
||||||
|
"fields": {
|
||||||
|
"question": 9,
|
||||||
|
"choice_text": "Orange"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 30,
|
||||||
|
"fields": {
|
||||||
|
"question": 9,
|
||||||
|
"choice_text": "Banana"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 31,
|
||||||
|
"fields": {
|
||||||
|
"question": 8,
|
||||||
|
"choice_text": "What is the difference betweeen history and you? History is in the past but you are my future."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 32,
|
||||||
|
"fields": {
|
||||||
|
"question": 1,
|
||||||
|
"choice_text": "Use both!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.choice",
|
||||||
|
"pk": 33,
|
||||||
|
"fields": {
|
||||||
|
"question": 2,
|
||||||
|
"choice_text": "Dinosaur"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"model": "polls.vote",
|
"model": "polls.vote",
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
@ -254,6 +502,114 @@
|
|||||||
"question": 1
|
"question": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 16,
|
||||||
|
"fields": {
|
||||||
|
"choice": 9,
|
||||||
|
"user": 1,
|
||||||
|
"question": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 17,
|
||||||
|
"fields": {
|
||||||
|
"choice": 6,
|
||||||
|
"user": 1,
|
||||||
|
"question": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 18,
|
||||||
|
"fields": {
|
||||||
|
"choice": 25,
|
||||||
|
"user": 2,
|
||||||
|
"question": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 19,
|
||||||
|
"fields": {
|
||||||
|
"choice": 15,
|
||||||
|
"user": 2,
|
||||||
|
"question": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 20,
|
||||||
|
"fields": {
|
||||||
|
"choice": 24,
|
||||||
|
"user": 4,
|
||||||
|
"question": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 21,
|
||||||
|
"fields": {
|
||||||
|
"choice": 25,
|
||||||
|
"user": 3,
|
||||||
|
"question": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 22,
|
||||||
|
"fields": {
|
||||||
|
"choice": 14,
|
||||||
|
"user": 3,
|
||||||
|
"question": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 23,
|
||||||
|
"fields": {
|
||||||
|
"choice": 28,
|
||||||
|
"user": 3,
|
||||||
|
"question": 9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 24,
|
||||||
|
"fields": {
|
||||||
|
"choice": 27,
|
||||||
|
"user": 6,
|
||||||
|
"question": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 25,
|
||||||
|
"fields": {
|
||||||
|
"choice": 15,
|
||||||
|
"user": 6,
|
||||||
|
"question": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 26,
|
||||||
|
"fields": {
|
||||||
|
"choice": 29,
|
||||||
|
"user": 6,
|
||||||
|
"question": 9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.vote",
|
||||||
|
"pk": 27,
|
||||||
|
"fields": {
|
||||||
|
"choice": 26,
|
||||||
|
"user": 1,
|
||||||
|
"question": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"model": "polls.sentimentvote",
|
"model": "polls.sentimentvote",
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
@ -361,5 +717,113 @@
|
|||||||
"question": 2,
|
"question": 2,
|
||||||
"vote_types": true
|
"vote_types": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 14,
|
||||||
|
"fields": {
|
||||||
|
"user": 1,
|
||||||
|
"question": 4,
|
||||||
|
"vote_types": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 15,
|
||||||
|
"fields": {
|
||||||
|
"user": 1,
|
||||||
|
"question": 3,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 16,
|
||||||
|
"fields": {
|
||||||
|
"user": 1,
|
||||||
|
"question": 2,
|
||||||
|
"vote_types": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 17,
|
||||||
|
"fields": {
|
||||||
|
"user": 2,
|
||||||
|
"question": 8,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 18,
|
||||||
|
"fields": {
|
||||||
|
"user": 2,
|
||||||
|
"question": 7,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 19,
|
||||||
|
"fields": {
|
||||||
|
"user": 4,
|
||||||
|
"question": 8,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 20,
|
||||||
|
"fields": {
|
||||||
|
"user": 3,
|
||||||
|
"question": 8,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 21,
|
||||||
|
"fields": {
|
||||||
|
"user": 3,
|
||||||
|
"question": 6,
|
||||||
|
"vote_types": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 22,
|
||||||
|
"fields": {
|
||||||
|
"user": 3,
|
||||||
|
"question": 9,
|
||||||
|
"vote_types": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 23,
|
||||||
|
"fields": {
|
||||||
|
"user": 6,
|
||||||
|
"question": 8,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 24,
|
||||||
|
"fields": {
|
||||||
|
"user": 6,
|
||||||
|
"question": 9,
|
||||||
|
"vote_types": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "polls.sentimentvote",
|
||||||
|
"pk": 25,
|
||||||
|
"fields": {
|
||||||
|
"user": 1,
|
||||||
|
"question": 8,
|
||||||
|
"vote_types": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"pk": 1,
|
"pk": 1,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$600000$aDh9a1PXxcXAb8z3YIjAPX$NVH24kt/wMad+0fZcCii738dfojI4vL2ffXOwNRuLz4=",
|
"password": "pbkdf2_sha256$600000$aDh9a1PXxcXAb8z3YIjAPX$NVH24kt/wMad+0fZcCii738dfojI4vL2ffXOwNRuLz4=",
|
||||||
"last_login": "2023-09-14T16:45:03.576Z",
|
"last_login": "2023-09-15T17:09:43.310Z",
|
||||||
"is_superuser": true,
|
"is_superuser": true,
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"first_name": "",
|
"first_name": "",
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"pk": 2,
|
"pk": 2,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$600000$quZKLKT8Ec3TQgpdqlCkpX$o+VOOnRDLGf64qjHb239Yvsre74tPkC8hw1qH1un/hk=",
|
"password": "pbkdf2_sha256$600000$quZKLKT8Ec3TQgpdqlCkpX$o+VOOnRDLGf64qjHb239Yvsre74tPkC8hw1qH1un/hk=",
|
||||||
"last_login": "2023-09-14T13:22:50.921Z",
|
"last_login": "2023-09-15T17:07:42.782Z",
|
||||||
"is_superuser": false,
|
"is_superuser": false,
|
||||||
"username": "tester1",
|
"username": "tester1",
|
||||||
"first_name": "",
|
"first_name": "",
|
||||||
@ -40,7 +40,7 @@
|
|||||||
"pk": 3,
|
"pk": 3,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$600000$1xGp6EDCoaljdTlSdVT1Mn$UID0Woeh8hwW7LtchH+hKzqdKTDeITTxQ/0DGvfG3CY=",
|
"password": "pbkdf2_sha256$600000$1xGp6EDCoaljdTlSdVT1Mn$UID0Woeh8hwW7LtchH+hKzqdKTDeITTxQ/0DGvfG3CY=",
|
||||||
"last_login": "2023-09-12T07:09:55.381Z",
|
"last_login": "2023-09-15T16:36:24.774Z",
|
||||||
"is_superuser": false,
|
"is_superuser": false,
|
||||||
"username": "tester3",
|
"username": "tester3",
|
||||||
"first_name": "",
|
"first_name": "",
|
||||||
@ -58,7 +58,7 @@
|
|||||||
"pk": 4,
|
"pk": 4,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$600000$fJJcIwAuIESYwZDBOqBv8t$YEDVCgg/xJOqAOiAdvGvvqgi1jgn1YfYHJE9yx2JWTA=",
|
"password": "pbkdf2_sha256$600000$fJJcIwAuIESYwZDBOqBv8t$YEDVCgg/xJOqAOiAdvGvvqgi1jgn1YfYHJE9yx2JWTA=",
|
||||||
"last_login": "2023-09-14T11:23:08.948Z",
|
"last_login": "2023-09-15T16:35:58.248Z",
|
||||||
"is_superuser": false,
|
"is_superuser": false,
|
||||||
"username": "tester2",
|
"username": "tester2",
|
||||||
"first_name": "",
|
"first_name": "",
|
||||||
@ -94,7 +94,7 @@
|
|||||||
"pk": 6,
|
"pk": 6,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$600000$5rNKsClojvcsBqzrEmAzy5$XpeAUCrzeLG42H+8o4HBVqifKd0cQuWcEhFax/dxS5M=",
|
"password": "pbkdf2_sha256$600000$5rNKsClojvcsBqzrEmAzy5$XpeAUCrzeLG42H+8o4HBVqifKd0cQuWcEhFax/dxS5M=",
|
||||||
"last_login": "2023-09-14T16:44:29.087Z",
|
"last_login": "2023-09-15T16:37:53.221Z",
|
||||||
"is_superuser": false,
|
"is_superuser": false,
|
||||||
"username": "tester4",
|
"username": "tester4",
|
||||||
"first_name": "",
|
"first_name": "",
|
||||||
@ -106,5 +106,23 @@
|
|||||||
"groups": [],
|
"groups": [],
|
||||||
"user_permissions": []
|
"user_permissions": []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "auth.user",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"password": "1234",
|
||||||
|
"last_login": null,
|
||||||
|
"is_superuser": false,
|
||||||
|
"username": "test",
|
||||||
|
"first_name": "",
|
||||||
|
"last_name": "",
|
||||||
|
"email": "",
|
||||||
|
"is_staff": false,
|
||||||
|
"is_active": true,
|
||||||
|
"date_joined": "2023-09-15T11:53:22.035Z",
|
||||||
|
"groups": [],
|
||||||
|
"user_permissions": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,8 +13,10 @@ class QuestionAdmin(admin.ModelAdmin):
|
|||||||
(None, {"fields": ["question_text"]}),
|
(None, {"fields": ["question_text"]}),
|
||||||
("Published date", {"fields": ["pub_date"], "classes": ["collapse"]}),
|
("Published date", {"fields": ["pub_date"], "classes": ["collapse"]}),
|
||||||
("End date", {"fields": ["end_date"], "classes": ["collapse"]}),
|
("End date", {"fields": ["end_date"], "classes": ["collapse"]}),
|
||||||
|
("Short Description", {"fields": ["short_description"], "classes": ["collapse"]}),
|
||||||
|
("Long Description", {"fields": ["long_description"], "classes": ["collapse"]}),
|
||||||
]
|
]
|
||||||
list_display = ["question_text", "pub_date", "end_date", "was_published_recently", "can_vote"]
|
list_display = ["question_text", "pub_date", "end_date", "was_published_recently", "can_vote", "trending_score"]
|
||||||
inlines = [ChoiceInline]
|
inlines = [ChoiceInline]
|
||||||
list_filter = ["pub_date", "end_date"]
|
list_filter = ["pub_date", "end_date"]
|
||||||
search_fields = ["question_text"]
|
search_fields = ["question_text"]
|
||||||
|
|||||||
18
polls/migrations/0015_question_trend_score.py
Normal file
18
polls/migrations/0015_question_trend_score.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.4 on 2023-09-15 07:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('polls', '0014_remove_question_down_vote_count_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='question',
|
||||||
|
name='trend_score',
|
||||||
|
field=models.FloatField(default=0.0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -46,6 +46,7 @@ class Question(models.Model):
|
|||||||
end_date = models.DateTimeField("date ended", null=True)
|
end_date = models.DateTimeField("date ended", null=True)
|
||||||
short_description = models.CharField(max_length=200, default="Cool kids have polls")
|
short_description = models.CharField(max_length=200, default="Cool kids have polls")
|
||||||
long_description = models.TextField(max_length=2000, default="No description provide for this poll.")
|
long_description = models.TextField(max_length=2000, default="No description provide for this poll.")
|
||||||
|
trend_score = models.FloatField(default=0.0, null=False, blank=False)
|
||||||
tags = models.ManyToManyField(Tag, blank=True)
|
tags = models.ManyToManyField(Tag, blank=True)
|
||||||
|
|
||||||
def was_published_recently(self):
|
def was_published_recently(self):
|
||||||
@ -157,6 +158,9 @@ class Question(models.Model):
|
|||||||
|
|
||||||
# ! Most of the code from https://stackoverflow.com/a/70869267
|
# ! Most of the code from https://stackoverflow.com/a/70869267
|
||||||
def upvote(self, user):
|
def upvote(self, user):
|
||||||
|
"""create new SentimentVote object that represent upvote (vote_types=True)
|
||||||
|
return True if user change the vote or vote for the first time else return False
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.sentimentvote_set.create(user=user, question=self, vote_types=True)
|
self.sentimentvote_set.create(user=user, question=self, vote_types=True)
|
||||||
self.save()
|
self.save()
|
||||||
@ -170,6 +174,9 @@ class Question(models.Model):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def downvote(self, user):
|
def downvote(self, user):
|
||||||
|
"""create new SentimentVote object that represent downvote (vote_types=False)
|
||||||
|
return True if user change the vote or vote for the first time else return False
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.sentimentvote_set.create(user=user, question=self, vote_types=False)
|
self.sentimentvote_set.create(user=user, question=self, vote_types=False)
|
||||||
self.save()
|
self.save()
|
||||||
@ -190,6 +197,38 @@ class Question(models.Model):
|
|||||||
def down_vote_count(self):
|
def down_vote_count(self):
|
||||||
return self.sentimentvote_set.filter(question=self, vote_types=False).count()
|
return self.sentimentvote_set.filter(question=self, vote_types=False).count()
|
||||||
|
|
||||||
|
def trending_score(self, up=None, down=None):
|
||||||
|
"""Return trend score base on the criteria below"""
|
||||||
|
published_date_duration = timezone.now() - self.pub_date
|
||||||
|
score = 0
|
||||||
|
|
||||||
|
if (published_date_duration.seconds < 259200): # Second unit
|
||||||
|
score += 100
|
||||||
|
elif (published_date_duration.seconds < 604800):
|
||||||
|
score += 75
|
||||||
|
elif (published_date_duration.seconds < 2592000):
|
||||||
|
score += 50
|
||||||
|
else:
|
||||||
|
score += 25
|
||||||
|
|
||||||
|
if (up == None) and (down == None):
|
||||||
|
score += ((self.up_vote_count/5) - (self.down_vote_count/5)) * 100
|
||||||
|
else:
|
||||||
|
score += ((up/5) - (down/5)) * 100
|
||||||
|
|
||||||
|
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
|
||||||
|
if self._state.adding:
|
||||||
|
try:
|
||||||
|
self.trend_score = self.trending_score()
|
||||||
|
except ValueError:
|
||||||
|
self.trend_score = self.trending_score(up=0, down=0)
|
||||||
|
super(Question, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Choice(models.Model):
|
class Choice(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -228,9 +267,25 @@ class Vote(models.Model):
|
|||||||
|
|
||||||
# ! Most of the code from https://stackoverflow.com/a/70869267
|
# ! Most of the code from https://stackoverflow.com/a/70869267
|
||||||
class SentimentVote(models.Model):
|
class SentimentVote(models.Model):
|
||||||
|
"""
|
||||||
|
Represents a sentiment vote for a poll question.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
user (User): The user who cast the sentiment vote.
|
||||||
|
question (Question): The poll question for which the sentiment vote is cast.
|
||||||
|
vote_types (bool): Indicates whether the sentiment vote is an upvote (True) or a downvote (False).
|
||||||
|
|
||||||
|
Note:
|
||||||
|
- When 'vote_types' is True, it represents an upvote or 'Like'.
|
||||||
|
- When 'vote_types' is False, it represents a downvote or 'Dislike'.
|
||||||
|
"""
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
||||||
vote_types = models.BooleanField()
|
vote_types = models.BooleanField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
"""
|
||||||
|
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']
|
unique_together = ['user', 'question']
|
||||||
@ -83,7 +83,7 @@
|
|||||||
<h2 class="text-2xl font-bold bg-gradient-to-r from-red-600 via-orange-600 to-yellow-600 bg-clip-text text-transparent lg:inline">Top Polls Today</h2>
|
<h2 class="text-2xl font-bold bg-gradient-to-r from-red-600 via-orange-600 to-yellow-600 bg-clip-text text-transparent lg:inline">Top Polls Today</h2>
|
||||||
<hr class="h-px my-4 bg-gray-200 border-0 dark:bg-gray-400" />
|
<hr class="h-px my-4 bg-gray-200 border-0 dark:bg-gray-400" />
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||||
{% for question in latest_question_list %}
|
{% for question in latest_question_list.trend_poll %}
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<!-- INFO -->
|
<!-- INFO -->
|
||||||
<div class="rounded-lg bg-white p-4 shadow-md border-solid border-2 border-yellow-500 relative z-10 transform translate-y-0 hover:translate-y-1 transition-transform">
|
<div class="rounded-lg bg-white p-4 shadow-md border-solid border-2 border-yellow-500 relative z-10 transform translate-y-0 hover:translate-y-1 transition-transform">
|
||||||
@ -129,7 +129,7 @@
|
|||||||
<h2 class="mb-4 text-2xl font-bold">All Polls</h2>
|
<h2 class="mb-4 text-2xl font-bold">All Polls</h2>
|
||||||
<hr class="h-px my-4 bg-gray-200 border-0 dark:bg-gray-400" />
|
<hr class="h-px my-4 bg-gray-200 border-0 dark:bg-gray-400" />
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3">
|
||||||
{% for question in latest_question_list %}
|
{% for question in latest_question_list.all_poll %}
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<!-- INFO -->
|
<!-- INFO -->
|
||||||
<div class="rounded-lg bg-white p-4 shadow-md border-solid border-2 border-neutral-500 relative z-10 transform translate-y-0 hover:translate-y-1 transition-transform">
|
<div class="rounded-lg bg-white p-4 shadow-md border-solid border-2 border-neutral-500 relative z-10 transform translate-y-0 hover:translate-y-1 transition-transform">
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class QuestionIndexViewTests(TestCase):
|
|||||||
"""
|
"""
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertQuerySetEqual(response.context["latest_question_list"], [])
|
self.assertQuerySetEqual(response.context["latest_question_list"]["all_poll"], [])
|
||||||
|
|
||||||
def test_past_question(self):
|
def test_past_question(self):
|
||||||
"""
|
"""
|
||||||
@ -24,7 +24,7 @@ class QuestionIndexViewTests(TestCase):
|
|||||||
question.save()
|
question.save()
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertQuerySetEqual(
|
self.assertQuerySetEqual(
|
||||||
response.context["latest_question_list"],
|
response.context["latest_question_list"]["all_poll"],
|
||||||
[question],
|
[question],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ class QuestionIndexViewTests(TestCase):
|
|||||||
future_question.pub_date = timezone.now() + timezone.timedelta(days=30)
|
future_question.pub_date = timezone.now() + timezone.timedelta(days=30)
|
||||||
future_question.save()
|
future_question.save()
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertQuerySetEqual(response.context["latest_question_list"], [])
|
self.assertQuerySetEqual(response.context["latest_question_list"]["all_poll"], [])
|
||||||
|
|
||||||
def test_future_question_and_past_question(self):
|
def test_future_question_and_past_question(self):
|
||||||
"""
|
"""
|
||||||
@ -54,7 +54,7 @@ class QuestionIndexViewTests(TestCase):
|
|||||||
|
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertQuerySetEqual(
|
self.assertQuerySetEqual(
|
||||||
response.context["latest_question_list"],
|
response.context["latest_question_list"]["all_poll"],
|
||||||
[past_question],
|
[past_question],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -72,6 +72,6 @@ class QuestionIndexViewTests(TestCase):
|
|||||||
|
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertQuerySetEqual(
|
self.assertQuerySetEqual(
|
||||||
response.context["latest_question_list"],
|
response.context["latest_question_list"]["all_poll"],
|
||||||
[question2, question1],
|
[question2, question1],
|
||||||
)
|
)
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class QuestionModelTests(TestCase):
|
|||||||
|
|
||||||
response = self.client.get(reverse("polls:index"))
|
response = self.client.get(reverse("polls:index"))
|
||||||
self.assertQuerySetEqual(
|
self.assertQuerySetEqual(
|
||||||
response.context["latest_question_list"],
|
response.context["latest_question_list"]["all_poll"],
|
||||||
[question],
|
[question],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
42
polls/tests/test_sentiment_model.py
Normal file
42
polls/tests/test_sentiment_model.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
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
|
||||||
|
class UpDownVoteViewTest(TransactionTestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUp(cls) -> None:
|
||||||
|
cls.user = User.objects.create_user(username="test_user", password="12345abc")
|
||||||
|
cls.q1 = create_question(question_text="test 1")
|
||||||
|
cls.client = Client()
|
||||||
|
|
||||||
|
def test_vote_up_once(self):
|
||||||
|
self.client.login(username="test_user", password="12345abc")
|
||||||
|
self.q1.upvote(self.user)
|
||||||
|
self.assertFalse(self.q1.upvote(self.user))
|
||||||
|
|
||||||
|
def test_vote_down_once(self):
|
||||||
|
self.client.login(username="test_user", password="12345abc")
|
||||||
|
self.q1.downvote(self.user)
|
||||||
|
self.assertFalse(self.q1.downvote(self.user))
|
||||||
|
|
||||||
|
def test_can_change_up_to_down(self):
|
||||||
|
self.client.login(username="test_user", password="12345abc")
|
||||||
|
self.q1.upvote(self.user)
|
||||||
|
self.q1.downvote(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, 0)
|
||||||
|
self.assertEqual(count_down, 1)
|
||||||
|
|
||||||
|
def test_can_change_up_to_down(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)
|
||||||
@ -8,6 +8,7 @@ from django.utils import timezone
|
|||||||
from django.urls import reverse_lazy, reverse
|
from django.urls import reverse_lazy, reverse
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth import authenticate, login
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
@ -29,10 +30,18 @@ class IndexView(generic.ListView):
|
|||||||
Return the last published questions that is published and haven't ended yet.
|
Return the last published questions that is published and haven't ended yet.
|
||||||
"""
|
"""
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
return Question.objects.filter(
|
all_poll_queryset = Question.objects.filter(
|
||||||
Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None)))
|
Q(pub_date__lte=now) & ((Q(end_date__gte=now) | Q(end_date=None)))
|
||||||
).order_by("-pub_date")
|
).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]
|
||||||
|
|
||||||
|
queryset = {'all_poll' : all_poll_queryset,
|
||||||
|
'trend_poll' : trend_poll_queryset,}
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class DetailView(LoginRequiredMixin, generic.DetailView):
|
class DetailView(LoginRequiredMixin, generic.DetailView):
|
||||||
"""
|
"""
|
||||||
@ -105,6 +114,13 @@ class SignUpView(generic.CreateView):
|
|||||||
success_url = reverse_lazy('login')
|
success_url = reverse_lazy('login')
|
||||||
template_name = 'registration/signup.html'
|
template_name = 'registration/signup.html'
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
valid = super(SignUpView, self).form_valid(form)
|
||||||
|
username, password = form.cleaned_data.get("username"), form.cleaned_data.get("password1")
|
||||||
|
user = authenticate(username=username, password=password)
|
||||||
|
login(self.request, user)
|
||||||
|
return valid
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def vote(request, question_id):
|
def vote(request, question_id):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user