Skip to content

Latest commit

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

1. Task:Add 3 roles

  1. Staff user
    1. Can add a new poll
    2. Can edit a poll
    3. Can delete a poll
  2. Regular user
    1. Can vote
    2. Can view a poll results
  3. Anonymous user
    1. Can only view a poll result

Step-by-step

  1. Enable only staff user to interact with polls

We have 3 views: detail, results and vote. User object can be fetched with the following.

defdetail(request, question_id):
user=request.user
...

We can restrict access with the following piece of code. Apply this to all 3 views.

defdetail(request, question_id):
ifnotrequest.user.is_staff:
raisePermissionDenied('You are not allowed to perform this action.')
...
  1. We don't want to click every time. Let's create test for vote, results and detail functionality. Read first:https://docs.djangoproject.com/en/3.2/topics/testing/overview/

Go to file tests.py and add the following code.

fromdjango.testimportTestCase, Clientfromdjango.contrib.auth.modelsimportUser
...
classStaffUserTests(TestCase):
defsetUp(self):
username='staff_user'password='test123'self.question=Question.objects.create(question_text='text', pub_date=timezone.now())
self.choice=Choice.objects.create(question=self.question, choice_text='text')
self.staff=User.objects.create_user(
username=username,
password=password,
is_staff=True,
)
self.client=Client()
deftest_detail_view(self):
self.client.force_login(self.staff)
response=self.client.get(reverse('polls:detail', kwargs={'question_id': self.question.pk}))
self.assertEqual(response.status_code, 200)

You can run tests with the following commands:

python manage.py test polls
python manage.py test polls.tests.StaffUserTests
python manage.py test polls.tests.StaffUserTests.test_detail_view

Add tests for results and vote.

...
def test_results_view(self):
self.client.force_login(self.staff)
response = self.client.get(reverse('polls:results', kwargs={'question_id': self.question.pk}))
self.assertEqual(response.status_code, 200)
def test_vote_view(self):
self.client.force_login(self.staff)
response = self.client.post(
reverse('polls:vote', kwargs={'question_id': self.question.pk}),
{'choice': self.choice.pk}
)
self.assertEqual(response.status_code, 302)
  1. Management commands Let's write custom management command so we can reset out db whenever we wish. Read first:https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/#management-commands-and-locales

First, we need to create folder management/commands and inside of it file named by our custom command - populate_db.py

fromdjango.contrib.auth.modelsimportUserfromdjango.core.management.baseimportBaseCommandstaff_username='staff_user'regular_user='regular_user'password='test123'classCommand(BaseCommand):
help='Populates database with dummy data'defcreate_users(self):
self.staff=User.objects.create_user(
username=staff_username,
password=password,
is_staff=True,
)
self.regular_user=User.objects.create_user(
username=regular_user,
password=password,
is_staff=False,
is_superuser=False
)
defhandle(self, *args, **options):
self.create_users()
print('Users created')

Now we can run our command by: python manage.py populate_db

  1. Enable anonymous user to view everything We have to allow anonymous user to check poll results. So remove restriction in detail and results view.
defdetail(request, question_id):
ifnotrequest.user.is_staff:
raisePermissionDenied('You are not allowed to perform this action.')
...
defresults(request, question_id):
ifnotrequest.user.is_staff:
raisePermissionDenied('You are not allowed to perform this action.')
  1. Add vote restriction for anonymous user We have 2 options with this: using decorators or manual check.
    1. Using decorators - redirect to login
fromdjango.contrib.auth.decoratorsimportlogin_required
...
@login_required(login_url='login')defvote(request, question_id):
...
  1. Manual check
defvote(request, question_id):
ifnotrequest.user.is_authenticated:
raisePermissionDenied('You are not allowed to perform this action.')
  1. Django admin

6.1 Add search in questions

# admin.pyclassQuestionAdmin(admin.ModelAdmin):
list_display= ('question_text', 'pub_date', 'was_published_recently')
search_fields= ['question_text']

6.2 Add filters in questions

# admin.pyclassQuestionAdmin(admin.ModelAdmin):
list_display= ('question_text', 'pub_date', 'was_published_recently')
list_filter= ['pub_date', ]
search_fields= ['question_text']

6.3 Show choices next to the questions

fromdjango.utils.htmlimportformat_htmlfrom .modelsimportQuestion, ChoiceclassQuestionAdmin(admin.ModelAdmin):
list_display= ('question_text', 'pub_date', 'was_published_recently', 'get_choices')
list_filter= ['pub_date',]
search_fields= ['question_text']
defget_choices(self, obj):
html=''choices=Choice.objects.filter(question=obj)
forchoiceinchoices:
html+=f'{choice.choice_text}<br>'returnformat_html(html)

6.4 Remove delete permission

classQuestionAdmin(admin.ModelAdmin):
...
defhas_delete_permission(self, request, obj=None):
returnFalse

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages