-
Notifications
You must be signed in to change notification settings - Fork 2
Desafio artur veloso #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c10b5eb
0606530
d480714
8358a22
edc7561
ef507a8
6728c2a
bb17e71
0ff7387
a71c55d
c6cb306
e62c669
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| *.pyc | ||
| .DS_Store | ||
| .venv | ||
| *.sqlite3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,24 @@ | ||
| from django.contrib import admin | ||
| from .models import Question, Alternatives, QuestionLogs | ||
|
|
||
| # Register your models here. | ||
| # Register admin models | ||
| admin.site.register(Question) | ||
|
|
||
| @admin.register(Alternatives) | ||
| class AlternativesAdmin(admin.ModelAdmin): | ||
| list_display = ( | ||
| 'alternative_order', | ||
| 'question', | ||
| 'alternative_text', | ||
| 'is_correct' | ||
| ) | ||
|
|
||
| @admin.register(QuestionLogs) | ||
| class QuestionLogsAdmin(admin.ModelAdmin): | ||
| list_display = ( | ||
| 'user', | ||
| 'question', | ||
| 'chosen_alternative', | ||
| 'is_correct', | ||
| 'answer_date' | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,58 @@ | ||
| from django.db import models | ||
| from django.contrib.auth.models import User | ||
|
|
||
| # Create your models here. | ||
| # Models | ||
| class Question(models.Model): | ||
| question_text = models.TextField(verbose_name="Questão") | ||
|
|
||
| def __str__(self): | ||
| return self.question_text | ||
|
|
||
| class Meta: | ||
| ordering = ('pk',) | ||
| verbose_name = 'Questão' | ||
| verbose_name_plural = 'Questões' | ||
|
|
||
| class Alternatives(models.Model): | ||
| alternative_order = models.CharField(max_length=4, verbose_name="Alternativa") | ||
| question = models.ForeignKey( | ||
| 'Question', | ||
| on_delete=models.CASCADE, | ||
| verbose_name="Questão" | ||
| ) | ||
| alternative_text = models.TextField(verbose_name="Questão") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Como estes são atributos de |
||
| is_correct = models.BooleanField( | ||
| verbose_name="Está correta?", | ||
| default=False | ||
| ) | ||
|
|
||
| def __str__(self): | ||
| return self.alternative_text | ||
|
|
||
| class Meta: | ||
| ordering = ('alternative_order',) | ||
| verbose_name = 'Alternativa' | ||
| verbose_name_plural = 'Alternativas' | ||
|
|
||
| class QuestionLogs(models.Model): | ||
| user = models.ForeignKey(User, verbose_name="Usuário", on_delete=models.CASCADE, null=True, blank=True) | ||
|
|
||
| question = models.ForeignKey( | ||
| 'Question', | ||
| on_delete=models.CASCADE, | ||
| verbose_name="Questão" | ||
| ) | ||
| chosen_alternative = models.CharField(max_length=4, verbose_name="Alternativa", null=True, blank=True) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Olha minha sugestão: Se ao invés de guardar o valor da alternativa, tivesse usado uma |
||
| is_correct = models.BooleanField( | ||
| verbose_name="Está correta?", | ||
| default=False | ||
| ) | ||
| answer_date = models.DateField(null=True, blank=True) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Campos |
||
|
|
||
| def __str__(self): | ||
| return self.question.question_text | ||
|
|
||
| class Meta: | ||
| ordering = ('pk',) | ||
| verbose_name = 'Log' | ||
| verbose_name_plural = 'Logs' | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <title>Logs</title> | ||
| </head> | ||
|
|
||
| <body> | ||
| <h1>Logs de respostas do usuário: {{ user }}</h1> | ||
| {% for log in logs %} | ||
| <p>{{ log.user }} | {{ log.question }} | {{ log.chosen_alternative }} | {% if log.is_correct %} Correto {% else %} Errado {% endif %} | {{ log.answer_date }}</p> | ||
| {% endfor %} | ||
| <a href="{% url 'question_home' %}">Home</a> | ||
| </form> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,142 @@ | ||
| from django.test import TestCase | ||
| from .models import Question, Alternatives, QuestionLogs | ||
|
|
||
| # Create your tests here. | ||
| # Tests | ||
| class TestViewQuestion(TestCase): | ||
|
|
||
| # Test home access | ||
| def test_home_view(self): | ||
| # Test Question Response | ||
| response_question = self.client.get('') | ||
| self.assertEqual( | ||
| 200, | ||
| response_question.status_code | ||
| ) | ||
|
|
||
| # Test question access | ||
| def test_question_view(self): | ||
|
|
||
| # Question 1 | ||
| question1 = Question.objects.create( | ||
| id = 1, | ||
| question_text = "Quanto é 1 + 1?" | ||
| ) | ||
|
|
||
| # Test Question Response with id error | ||
| response_question = self.client.get('/2/') | ||
| self.assertEqual( | ||
| 404, | ||
| response_question.status_code | ||
| ) | ||
|
|
||
| # Test Question Response | ||
| response_question = self.client.get('/1/') | ||
| self.assertEqual( | ||
| 200, | ||
| response_question.status_code | ||
| ) | ||
|
|
||
| # Test the return of the question object | ||
| self.assertEqual( | ||
| question1, | ||
| response_question.context["questions"]['question_complete'] | ||
| ) | ||
|
|
||
| # Test the return of the question text | ||
| self.assertEqual( | ||
| "Quanto é 1 + 1?", | ||
| response_question.context["questions"]['question'], | ||
| ) | ||
|
|
||
| # Test the feedback if you have no alternatives for this question | ||
| self.assertEqual( | ||
| 0, | ||
| response_question.context["questions"]['alternatives'].count(), | ||
| ) | ||
|
|
||
| alternative1 = Alternatives.objects.create( | ||
| alternative_order = 'a', | ||
| question = question1, | ||
| alternative_text = "2", | ||
| is_correct = True | ||
| ) | ||
|
|
||
| alternative2 = Alternatives.objects.create( | ||
| alternative_order = 'b', | ||
| question = question1, | ||
| alternative_text = "10", | ||
| is_correct = False | ||
| ) | ||
|
|
||
| response_question = self.client.get('/1/') | ||
| # Test the feedback if you have one or more alternatives for this question | ||
| self.assertEqual( | ||
| 2, | ||
| response_question.context["questions"]['alternatives'].count(), | ||
| ) | ||
|
|
||
| # Test anser access | ||
| def test_answer_view(self): | ||
| question1 = Question.objects.create( | ||
| id = 1, | ||
| question_text = "Quanto é 1 + 1?" | ||
| ) | ||
|
|
||
| alternative1 = Alternatives.objects.create( | ||
| alternative_order = 'a', | ||
| question = question1, | ||
| alternative_text = "2", | ||
| is_correct = True | ||
| ) | ||
|
|
||
| alternative2 = Alternatives.objects.create( | ||
| alternative_order = 'b', | ||
| question = question1, | ||
| alternative_text = "10", | ||
| is_correct = False | ||
| ) | ||
|
|
||
| response_answer = self.client.post( | ||
| '/resposta/', | ||
| {'answer': alternative1.id} | ||
| ) | ||
|
|
||
| # Testar se deu certo o acesso | ||
| self.assertEqual( | ||
| 200, | ||
| response_answer.status_code | ||
| ) | ||
|
|
||
| # Testar se a respostar está correta | ||
| self.assertEqual( | ||
| True, | ||
| response_answer.context["is_correct"] | ||
| ) | ||
|
|
||
| # Testar se foi gerado o log | ||
| self.assertEqual( | ||
| True, | ||
| response_answer.context["is_correct"] | ||
| ) | ||
|
|
||
| # Testar um acesso errado a url | ||
| response_answer = self.client.post( | ||
| '/resposta/123', | ||
| {'answer': 'a'} | ||
| ) | ||
|
|
||
| self.assertEqual( | ||
| 404, | ||
| response_answer.status_code | ||
| ) | ||
|
|
||
| # Testar uma resposta errada | ||
| response_answer = self.client.post( | ||
| '/resposta/', | ||
| {'answer': alternative2.id} | ||
| ) | ||
|
|
||
| self.assertEqual( | ||
| False, | ||
| response_answer.context["is_correct"] | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,12 @@ | ||
| #coding: utf8 | ||
|
|
||
| from django.urls import path, re_path | ||
| from django.urls import path | ||
|
|
||
| from . import views | ||
|
|
||
| urlpatterns = [ | ||
| re_path(r'^$', views.question, name='question'), | ||
| re_path(r'^resposta/$', views.question_answer, name='question_answer'), | ||
|
|
||
| path('', views.home, name='question_home'), | ||
| path('<int:id>/', views.question, name='question'), | ||
| path('resposta/', views.question_answer, name='question_answer'), | ||
| path('log-questoes/', views.logs, name='logs'), | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boa 👍
Usou a nomenclatura certa para as coisas não ficarem confusas.
Answersempre foi uma escolha pior, porque aqui o que importa são as alternativas da questão, as respostas são uma coisa ligada ao usuário e assim devem estar relacionadas à tabela de ligação (neste casoQuestionLogs).Apenas para lembrar, normalmente se usa nomes no singular para as classes dos modelos 😉