In my project, I've got different types of Users like this:
User
|-Client
|-Employee
|-Technical Manager
|-Service Manager
|-Production Manager
No user can access the view of other user by url
. A client cannot access profile of a Technical Manager through the url /officer/profile
which is assigned for Technical Manager's profile.
In order to do so, In my Client class
in the models.py
, I used this code snippet:
class Client(models.Model):
class Meta:
permissions = (
('view_client', 'view_Client'),
)
Then for each view I used a decorator like this:
@permission_required(lambda u: u.has_perm('authentication.view_client'))
Then I'm logging in as a technical manager and trying to access with this url:
/client/profile
Then I got the error function object is not iterable
.
I was creating my user in an app called authentication
. The models,py
looks like this:
'
@python_2_unicode_compatible
class Profile(models.Model):
user = models.OneToOneField(User)
user_sex = (('MALE', 'Male'), ('FEMALE', 'Female'))
sex = models.CharField(max_length=6, default='Male', choices=user_sex)
address = models.CharField(max_length=250, null=True, blank=True)
city = models.CharField(max_length=250, null=True, blank=True)
state = models.CharField(max_length=250, null=True, blank=True)
country = models.CharField(max_length=250, null=True, blank=True)
phone = PhoneNumberField(blank=True)
zip = models.IntegerField(null=True, blank=True)
about = models.CharField(max_length=250, null=True, blank=True)
email_confirmed = models.BooleanField(default=False)
account_type = models.IntegerField(default=-1)
class Meta:
db_table = 'auth_profile'
class Employee(models.Model):
user = models.OneToOneField(User)
manager = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
designation = models.CharField(max_length=6)
class Meta:
db_table = 'auth_employee'
class Client(models.Model):
user = models.OneToOneField(User)
class Meta:
db_table = 'auth_client'
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
if instance.profile.account_type == 0:
if not Client.objects.filter(user=instance).exists():
Client.objects.create(user=instance)
instance.client.save()
else:
instance.client.save()
if instance.profile.account_type == 1 or instance.profile.account_type == 2 or instance.profile.account_type == 3:
if not Employee.objects.filter(user=instance).exists():
Employee.objects.create(user=instance)
instance.employee.save()
else:
instance.employee.save()
'
Profile class is kinda big. Please ignore it. Now what I wanted is that I would assign the permission each time a different user has been created of any types.
How to resolve the error and how can I accomplish this, so that one type of user cannot access the view of others' by typing the url?
Edited after the comment from souldeux
Here is one of my views where a client can update his contact info:
@login_required(login_url='/login/')
@permission_required(lambda u: u.has_perm('authentication.view_client'))
def contact(request):
user = request.user
if request.method == 'POST':
# form = ContactForm()
form = ContactForm(request.POST)
if form.is_valid():
user.profile.address = form.cleaned_data.get('address')
user.profile.city = form.cleaned_data.get('city')
user.profile.state = form.cleaned_data.get('state')
user.profile.country = form.cleaned_data.get('country')
user.profile.phone = form.cleaned_data.get('phone')
user.profile.zip = form.cleaned_data.get('zip')
user.save()
messages.add_message(request,
messages.SUCCESS,
'Your contact was successfully edited.')
else:
form = ContactForm(instance=user, initial={
'address': user.profile.address,
'city': user.profile.city,
'state': user.profile.state,
'country': user.profile.country,
'phone': user.profile.phone,
'zip': user.profile.zip,
})
return render(request, 'client/client_contact.html', {'form': form})
And the error I got:
TypeError at /client/picture
'function' object is not iterable
Request Method: GET
Request URL: http://127.0.0.1:8000/client/picture
Django Version: 1.11.6
Exception Type: TypeError
Exception Value:
'function' object is not iterable
Exception Location: /usr/local/lib/python2.7/dist-packages/django/contrib/auth/models.py in has_perms, line 285
Python Executable: /usr/bin/python2.7
Python Version: 2.7.12
Python Path:
['/home/shamsad/PycharmProjects/OpenGMS',
'/home/shamsad/PycharmProjects/OpenGMS',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/home/shamsad/.local/lib/python2.7/site-packages',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/lib/python2.7/dist-packages/gtk-2.0']
Server time: Sun, 29 Oct 2017 16:21:25 +0000