diff --git a/pollsapp/api_requests_detail.txt b/pollsapp/api_requests_detail.txt new file mode 100644 index 0000000..b975728 --- /dev/null +++ b/pollsapp/api_requests_detail.txt @@ -0,0 +1,184 @@ +Tracks API: + + 1. Tracks List + Url: http://localhost:8000/api/tracks/ + method: GET + Response: [ + { + "id": 2, + "track_text": "mmmmm" + }, + { + "id": 4, + "track_text": "mnjkl" + } + ] + 2. Tracks Create + Url: http://localhost:8000/api/tracks/ + method: POST + Request: + { + "track_text": "ssss" + } + Response: + { + "id": 7, + "track_text": "ssss" + } + 3. Tracks Detail + Url: http://localhost:8000/api/tracks/2/ #2 means track id + method: GET + Response: + { + "id": 2, + "track_text": "mmmm" + } + 4. Tracks Edit + Url: http://localhost:8000/api/tracks/2/ #2 means track id + method: PUT + Request: + { + "track_text": "mmmm123" + } + Response: + { + "id": 2, + "track_text": "mmmm123" + } + + 5. Tracks Delete + Url: http://localhost:8000/api/tracks/2/ #2 means track id + method: DELETE + + 6. Questions of a particular tarck + Url: http://localhost:8000/api/tracks/2/questions/ #2 means track id + method: GET + Response: [ + { + "id": 1, + "question_text": "asd", + "track": 2 + }, + { + "id": 6, + "question_text": "qqqqwscddddd", + "track": 2 + } + ] +User Choice API: + + 1. User Choice List + Url: http://localhost:8000/api/userchoice/ + method: GET + Response: [ + { + "id": 1, + "question": 1, + "choice": 1, + "is_correct": false + }, + { + "id": 2, + "question": 1, + "choice": 2, + "is_correct": true + } + ] + 2. User Choice Create + Url: http://localhost:8000/api/userchoice/ + method: POST + Request: + { + "question": 1, + "choice": 3, + "is_correct": true + } + Response: + { + "id": 8, + "question": 1, + "choice": 3, + "is_correct": true + } + 3. User Choice Detail + Url: http://localhost:8000/api/userchoice/8/ #2 means user choice id + method: GET + Response: + { + "id": 8, + "question": 1, + "choice": 3, + "is_correct": true + } + 4. User Choice Edit + Url: http://localhost:8000/api/userchoice/8/ #2 means user choice id + method: PUT + Request: + { + "id": 8, + "question": 1, + "choice": 3, + "is_correct": false + } + Response: + { + "id": 8, + "question": 1, + "choice": 3, + "is_correct": false + } + + 5. User Choice Delete + Url: http://localhost:8000/api/userchoice/2/ #2 means user choice id + method: DELETE + +Questions API: + +Added track to question model, so API's for create & edit will change + + 1. Question Create + Url: http://localhost:8000/api/questions/ + method: POST + Request: + { + "question_text": "qqqqq", + "track": 2 + } + Response: + { + "id": 7, + "question_text": "qqqqq", + "track": 2 + } + 2. Question Update + Url: http://localhost:8000/api/questions/7/ #7 means question id + method: POST + Request: + { + "question_text": "qqqqq12", + "track": 2 + } + Response: + { + "id": 7, + "question_text": "qqqqq12", + "track": 2 + } + + 3. Correct answers count of a particular question + Url: http://localhost:8000/api/questions/2/correct_answers/ #2 means question id + method: GET + Response: + { + "count": 1, + "question": "123" + } + + 4. Wrong answers count of a particular question + Url: http://localhost:8000/api/questions/2/wrong_answers/ #2 means question id + method: GET + Response: + { + "count": 2, + "question": "123" + } \ No newline at end of file diff --git a/pollsapp/polls/admin.py b/pollsapp/polls/admin.py index bd9ecc4..ff55a6b 100644 --- a/pollsapp/polls/admin.py +++ b/pollsapp/polls/admin.py @@ -1,7 +1,9 @@ from django.contrib import admin -from .models import Question, Choice +from .models import Track, Question, Choice, UserChoice # Register your models here. admin.site.register(Question) admin.site.register(Choice) +admin.site.register(Track) +admin.site.register(UserChoice) diff --git a/pollsapp/polls/api.py b/pollsapp/polls/api.py index 5e46693..e5ad4bc 100644 --- a/pollsapp/polls/api.py +++ b/pollsapp/polls/api.py @@ -1,23 +1,71 @@ -from django.conf.urls import url, include -from django.contrib.auth.models import User -from rest_framework import routers, serializers, viewsets +from rest_framework import serializers, viewsets +from rest_framework.response import Response +from rest_framework.decorators import action + +from .models import Track, Question, Choice, UserChoice + + +class TrackSerializer(serializers.ModelSerializer): + class Meta: + model = Track + fields = ('id', 'track_text') -from .models import Question, Choice class QuesSerializer(serializers.ModelSerializer): + class Meta: model = Question - fields = ('id', 'question_text') + fields = ('id', 'question_text', 'track') + class ChoiceSerializer(serializers.ModelSerializer): class Meta: model = Choice fields = ('id', 'question', 'choice_text', 'votes') + +class UserChoiceSerializer(serializers.ModelSerializer): + class Meta: + model = UserChoice + fields = ('id', 'question', 'choice', 'is_correct') + + +class TrackViewSet(viewsets.ModelViewSet): + queryset = Track.objects.all() + serializer_class = TrackSerializer + + @action(detail=True, methods=['get']) + def questions(self, request, pk=None): + track_questions = Question.objects.filter(track_id=pk) + page = self.paginate_queryset(track_questions) + if page is not None: + serializer = QuesSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = QuesSerializer(track_questions, many=True) + return Response(serializer.data) + + class QuesViewSet(viewsets.ModelViewSet): queryset = Question.objects.all() serializer_class = QuesSerializer + @action(detail=True, methods=['get']) + def correct_answers(self, request, pk=None): + correct_answers_count = UserChoice.objects.filter(question_id=pk, is_correct=True).count() + return Response({'count': correct_answers_count, 'question': self.get_object().question_text}) + + @action(detail=True, methods=['get']) + def wrong_answers(self, request, pk=None): + wrong_answers_count = UserChoice.objects.filter(question_id=pk, is_correct=False).count() + return Response({'count': wrong_answers_count, 'question': self.get_object().question_text}) + + class ChoiceViewSet(viewsets.ModelViewSet): queryset = Choice.objects.all() serializer_class = ChoiceSerializer + + +class UserChoiceViewSet(viewsets.ModelViewSet): + queryset = UserChoice.objects.all() + serializer_class = UserChoiceSerializer diff --git a/pollsapp/polls/migrations/0002_auto_20190330_1528.py b/pollsapp/polls/migrations/0002_auto_20190330_1528.py new file mode 100644 index 0000000..c5d2037 --- /dev/null +++ b/pollsapp/polls/migrations/0002_auto_20190330_1528.py @@ -0,0 +1,27 @@ +# Generated by Django 2.1.4 on 2019-03-30 15:28 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('polls', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Track', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('track_text', models.CharField(max_length=200)), + ], + ), + migrations.AddField( + model_name='question', + name='track', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='polls.Track'), + preserve_default=False, + ), + ] diff --git a/pollsapp/polls/migrations/0003_userchoice.py b/pollsapp/polls/migrations/0003_userchoice.py new file mode 100644 index 0000000..b5b231e --- /dev/null +++ b/pollsapp/polls/migrations/0003_userchoice.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.4 on 2019-03-30 16:30 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('polls', '0002_auto_20190330_1528'), + ] + + operations = [ + migrations.CreateModel( + name='UserChoice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_correct', models.BooleanField(default=False)), + ('choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Choice')), + ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Question')), + ], + ), + ] diff --git a/pollsapp/polls/models.py b/pollsapp/polls/models.py index 024ae52..8b3f129 100644 --- a/pollsapp/polls/models.py +++ b/pollsapp/polls/models.py @@ -1,16 +1,22 @@ from django.db import models from django.utils import timezone -import datetime + # Create your models here. +class Track(models.Model): + track_text = models.CharField(max_length=200) + + class Question(models.Model): question_text = models.CharField(max_length=200) - pub_date = models.DateTimeField(blank=True,null=True) + pub_date = models.DateTimeField(blank=True, null=True) created_date = models.DateTimeField(default=timezone.now) + track = models.ForeignKey(Track, on_delete=models.CASCADE) def __str__(self): return self.question_text + class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) @@ -19,3 +25,9 @@ class Choice(models.Model): def __str__(self): return self.choice_text + +# purpose of this model is to store each question with choice and answer type weather it is correct or wrong +class UserChoice(models.Model): + question = models.ForeignKey(Question, on_delete=models.CASCADE) + choice = models.ForeignKey(Choice, on_delete=models.CASCADE) + is_correct = models.BooleanField(default=False) diff --git a/pollsapp/polls/tests.py b/pollsapp/polls/tests.py index c6fffb3..5c96fe4 100644 --- a/pollsapp/polls/tests.py +++ b/pollsapp/polls/tests.py @@ -1,8 +1,7 @@ from django.test import TestCase -# Create your tests here. -from django.contrib.auth.models import User +# Create your tests here. class QuestionTest(TestCase): def test_question(self): diff --git a/pollsapp/polls/urls.py b/pollsapp/polls/urls.py index 9b8863b..12e2f33 100644 --- a/pollsapp/polls/urls.py +++ b/pollsapp/polls/urls.py @@ -7,7 +7,12 @@ router = routers.SharedAPIRootRouter() router.register(r'questions', api.QuesViewSet) router.register(r'choices', api.ChoiceViewSet) +router.register(r'tracks', api.TrackViewSet) +router.register(r'userchoice', api.UserChoiceViewSet) + urlpatterns = [ path('', views.index, name='index'), + path('track/list/', views.tracks_list, name="tracks_list"), + path('update-track//', views.track_info, name="track_info"), ] diff --git a/pollsapp/polls/views.py b/pollsapp/polls/views.py index a903ff3..e0ab9e5 100644 --- a/pollsapp/polls/views.py +++ b/pollsapp/polls/views.py @@ -1,6 +1,59 @@ from django.http import HttpResponse +from rest_framework.decorators import api_view +from rest_framework.response import Response +from rest_framework import status +from .models import Track, Question, Choice +from .api import TrackSerializer def index(request): return HttpResponse("Hello, world. You're at the polls index.") - \ No newline at end of file + + +@api_view(['GET', 'POST']) +def tracks_list(request): + """ + List all tracks, or create a new track. + """ + if request.method == 'GET': + tier = Track.objects.all() + serializer = TrackSerializer(tier, many=True) + return Response(serializer.data) + + elif request.method == 'POST': + data = request.data + serializer = TrackSerializer(data=data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + return Response( + serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +@api_view(['GET', 'POST', 'DELETE']) +def track_info(request, pk): + """ + Get, udpate, or delete a specific track + """ + try: + track = Track.objects.get(pk=pk) + except Track.DoesNotExist: + return Response(status=status.HTTP_404_NOT_FOUND) + + if request.method == 'GET': + serializer = TrackSerializer(track) + return Response(serializer.data) + + elif request.method == 'POST': + serializer = TrackSerializer(track, data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data) + else: + return Response( + serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == 'DELETE': + track.delete() + return Response(status=status.HTTP_204_NO_CONTENT)