I have a web app where a user signs in and begins entering items for a ToDoList
. The base.html
is wrapped in an is_authenticated
check so users cannot see anything in the app until they have logged in. I was doing some testing with:
User2
ToDoListItem
DetailView
http://localhost:8000/to_do_list/to_do_item/72
At this point I realized that the DetailView would allow User2
to see the details for any ToDoListItem
for User1
just by entering in an existing pk
into: http://localhost:8000/to_do_list/to_do_item/<int:pk>
.
path('to_do_item/<int:pk>', views.ToDoListItemDetail.as_view(), name='todo-item-detail'),
class ToDoListItemDetail(DetailView):
model = ToDoListItem
{% extends 'base.html' %}
{% block content %}
<a href="/">Home</a>
<h1>DetailView for 'ToDoListItem' model</h1>
<p>TaskTitle: '{{ object.title }}'</p>
<p>Complete: '{{ object.is_complete }}'</p>
<p>User: '{{ object.user}}'</p>
{% endblock %}
What is the recommended way to prevent this from happening? I am considering the following:
ToDoListItem.objects.filter(user=request.user)
)ToDoListItem
.get_context_data()
for the DetailView and check user ownership there (similar to no. 1, but within the DetailView)Is there a way to limit a user to only see their own data throughout an application without implementing this logic every time it is needed?
You can filter in the DetailView
as well, by overriding the get_queryset
method [Django-doc] :
from django.contrib.auth.mixins import LoginRequiredMixin
class ToDoListItemDetail( DetailView):
model = ToDoListItem
def (self, *args, **kwargs):
return super(ToDoListItemDetail, self).get_queryset(
*args, **kwargs
).filter(user=self.request.user)
Django will, behind the curtains, always call get_queryset(..)
. By default this function returns the queryset of the model
you specified with all objects. But you thus can filter it further down.
Django's get_object
method [Django-doc] will then further filter it down with the id
and/or slug
, but if you already filter out the elements that do not belong to the self.request.user
, then this can thus only result in an query returning no results.
It also makes sense to here add the LoginRequiredMixin
[Django-doc] to your class, since in case the user did not log in, you probably want to redirect hem/her to the login screen.
There is a permission named: ¨can read¨ that allow you to handle the access. For example:
class FruitEdit(PermissionRequiredMixin,DetailView):
permission_required = 'app.read_fruit'
...
I hope you can solve it
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.