Reputation: 27
Just started Django last week and I am facing this problem regarding two types of users (normal and VIP) and how to restrict normal users from viewing VIP contents.
I am using Django with MySQL. My site does not requires user to signup but instead, I will be giving them username/password. I manually creates user via Django admin and group them according to VIP or normal. I will be uploading contents (again via admin) and I have a Boolean check-box that determine whether it is a VIP content or not.
What I done so far:
FAQ.html
{% extends 'base.html' %}
...skipping...
{% for faqs in fq reversed %}
<a href="{% url 'faq_topics' faqs.pk %}">{{ faqs.name }}</a>
{{ endfor }}
faq_topics.html
<h2>{{ faqs.name }}</h2>
<h6 style="padding: 20px 20px 20px 20px">{{ faqs.description|linebreaksbr }}</h6>
urls.py
urlpatterns = [
path('faq/', views.faq, name='faq'),
url(r'^faq/(?P<pk>\d+)/$', views.faq_topics, name='faq_topics'),]
views.py
def is_user(user):
return user.groups.filter(name='User').exists()
def is_vip(user):
return user.groups.filter(name='VIP').exists()
@login_required
@user_passes_test(is_user)
def faq(request):
fq = FAQ.objects.filter(vip_only=False)
return render(request, 'faq.html', {'fq':fq})
models.py
class FAQ(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=300)
vip_only = models.BooleanField(default=False)
Error Case
3 FAQ entries are made, the first one is classified as VIP only.
When a normal user log in into FAQ section, he/she will only see 2 contents
Welcome to FAQ section
127.0.0.1:8000/faq/3/
127.0.0.1:8000/faq/2/
However, the user can easily guess that faq/1/ exists and when they actually tries, they can have access to vip contents too.
I have been searching the web for the past 2 days, I learn how to user @user_passes_test to restrict users and objects.filter(vip_only=False) to restrict contents.
Additionally, I wish to have my views.py controlling the contents for both kind of user but I have yet to implement that yet. Will be very grateful if someone can teach me how to implement "2 views in one templates".
I have read from,
show different content based on logged in user django
django - 2 views in one template
My solution for splitting user
@login_required
def faq(request):
'''user is separate using groups'''
if request.user.is_superuser or request.user.groups.filter(name='VIP').exists():
fq = FAQ.objects.all()
else:
fq = FAQ.objects.filter(vip_only=False)
return render(request, 'faq.html', {'fq':fq})
Upvotes: 0
Views: 468
Reputation: 3308
You should do something like this
def faq(request):
if request.user.is_superuser:
fq = FAQ.objects.all()
else:
fq = FAQ.objects.filter(vip_only=False)
return render(request, 'faq.html', {'fq':fq})
You can also use similar approach for doing things in the template:
{% if user.is_superuser %}
#...show what you only want to show the superuser
{% endif %}
And in your method for the single faq, do something like:
def faq_topics(request, pk):
faq_item=FAQ.objects.get(id=pk)
if not request.user.is_superuser and not request.user.groups.filter(name='VIP').exists():
if fqa_item.vip_only:
return render(request, 'path_to_access_error_template', {'fq':faq_nr})
return render(request, 'faq_item.html', {'fq':faq_nr})
Upvotes: 1