how adding new colum to permission table - python

i am django new bay, i do a lot search but no result.
i need to add client_id to django permission model ( save and retrieve ), so when saving user permission client_id should saved with permission and when using has_perm it should check permission for current user for current client_id
adding example :
user.user_permissions.add(permiObject, request.session['ClientId'])
in template if i check :
{% if perms.app_name.perm_code %}
this check should be for current ClientId
Django Permission model field is : name, content_type, codename
i need it like this : : name, content_type, codename, client_id

I hate to give such answer, because it is not an answer to you direct question, but it really looks like an XY Problem here.
If I understand you correctly, you want to add permission for each user specific per client ID.
The idea behind the Django permissions is that they are supposed to be created at the time of migration, i.e. before your server ever starts to run. Here you add something unnatural, clients are added at runtime hence you also need to modify permissions at runtime. So it looks like Django permissions is not what you need.
What I would do if I were you is simply add a model for my own permissions and connect it to user via the foreign keys.
For example (pseudo code):
class MyPermission(Model):
name = models.CharField(max_length=10)
client = models.CharField(max_length=10)
user = models.ForeignKey(User, on_delete=models.CASCADE)
Run the migrations, then to add some user a new permission:
user.mypermission_set.create(name="write", client="123")
And to test if user has a permission:
user.mypermission_set.filter(name="write", client="123").exists()
So hope this helps, not exactly the way you wanted but gives the same functionality, if I understood you correctly.
PS: Maybe you will have to define a custom user model, not sure if Django will simply accept using mypermission_set with the standard user model, didn't test it.

Related

django-password-reset - how to set attributes

I am trying to use django-password-reset (https://pypi.python.org/pypi/django-password-reset/0.2) to allow users recovering their passwords.
django-password-reset provides a form where the user can enter their username or email address, and tries to find one of those in the database.
In my project, the user has no username field - only the email field.
Thus, I need to make it search users by the 'email' field only, and not by the 'username' field, which does not exist in my system.
The projects documentation says there are attributes to change this behavior:
http://django-password-reset.readthedocs.org/en/latest/views.html.
However, I simply cannot find out how to set these attributes.
Can someone help?
Just override Recover view like so:
class MyRecover(Recover):
search_fields = ['email']
myrecover = MyRecover.as_view()
because there are two recover urls, you need to pass the one with signature first and then the overridden one and then the included one, seems not very DRY, but it's the only way to make the urls be dispatched correctly:
url(r'^recover/(?P<signature>.+)/$', 'password_reset_recover.views.recover_done',
name='password_reset_sent'),
# next we override our url, assuming your app name is called 'core'
url(r'^recover/$', 'core.views.myrecover', name='password_reset_recover'),
url(r'^/', include('password_reset.urls')),
The documentation for django-password-reset says that it uses django.contrib.auth.models.User (the django built in User model) to search for username or email. So here a username would exist.
If you want to change the functionality of the django-password-reset you can go into the forms.py file and change the form's search_fields variable (and other logic) so that it only searches by email.
Here is the hyperlink to the forms.py:
https://github.com/brutasse/django-password-reset/blob/master/password_reset/forms.py
I'd start with changing the PasswordRecoveryForm

get user profile in django

hello i'm new in python and django
I need a view that get current user profile I know I shoud use get_profile from User but I don't know how to use it . i read the django document and It didn't help me.
this is what I found from doc:
from django.contrib.auth.models import User
profile=request.user.get_profile()
Django's documentation says it all, specifically the part Storing additional information about users. First you need to define a model somewhere in your models.py with fields for the additional information of the user:
models.py
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
accepted_eula = models.BooleanField()
favorite_animal = models.CharField(max_length=20, default="Dragons.")
Then, you need to indicate that this model (UserProfile) is the user profile by setting AUTH_PROFILE_MODULE inside your settings.py:
settings.py
...
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
...
You need to replace accounts with the name of your app. Finally, you want to create a profile every time a User instance is created by registering a post_save handler, this way every time you create a user Django will create his profile too:
models.py
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
accepted_eula = models.BooleanField()
favorite_animal = models.CharField(max_length=20, default="Dragons.")
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
Accessing the Profile
To access the current user's profile in your view, just use the User instance provided by the request, and call get_profile on it:
def your_view(request):
profile = request.user.get_profile()
...
# Your code
Basically django User models will provide access only for the fields ( firstname,lastname,email,password,is_staff,is_active,last_login).
However if we want to add any extra fields to this model, say we need to add a new column named dateofbirth for every user, then we need to add a column named DOB into User model. But this is not possible as we aren't able to edit django User models.
To achieve this either
1.We can have a separate new table with email id & DOB column, such that a column in User model is mapped with a column in the new table. But this will create a new db instance for every db request. Say if u want to find the DOB of a customer,
First we need to fetch the value of mapped id of a customer from the
User table.
WIth the above value, get DOB from the new table.
In the second method,
Instead of using django User model, use your own customize model with all the fields needed. However if any updation related to security or some enhancement made to django User model we can't use it directly. We need to do more code changes at our end( wherever we use our customize models.) This will be a bit pain for a developer to identify the code & make changes.
To overcome the above issues, django introduce django profile which is very simple and more flexible. The advantages are
Updation/enhancement to the User model can be applied without modifying the code much
No need of creating new db instance to fetch the extra values.
Since the field has onetoone mapping deletion of data from one table will delete others also.
More secure, since we use django models ( no sql injection)
How to Use this:
In settings.py create a variable AUTH_PROFILE_MODULE = "appname.profiletable"
In models.py, create a new table with the fields needed and make sure that the id in User model is onetoone mapped with new table.
create a signal which inserts a row into the new table whenever a new entry is added into User model.
The value in the new table can be accessed using User object itself.
Say, we created a new table extrauser which has DOB, emailid. To find the DOB of a customer, use
a=User.objects.get(email='x#x.xom')
a.get_profile().DOB will give the dateofbirth value from extrauser table.
Hope the above details make you clear in understanding django profile. Incase of any help further, let me know. I have used django profile in my project.
Old question but I thought anyone seeing it today may benefit from this:
Django 1.5 adds the ability to - easily - extend the User model. This may be preferable as you now only got one object to deal with rather than two! Seems the more modern way.
https://hurricanelabs.com/blog/django-user-models/
You need to specify which class is your "Profile" by setting AUTH_PROFILE_MODULE = 'accounts.UserProfile' (for example)
https://docs.djangoproject.com/en/1.4/topics/auth/

How the datas are connected to the specific user ID?

I'm new to Django and python. I've done login forms but I need to know. How can I connect the contents of the page with the user.
For example: It's a Q&A site. When you logged in, It shows profile page with the questions that user asked before. How the datas are linked to the specific user ID in the model?
Can it be done using the User object? If so, could you give me some simple example with the script?
Thank you.
Anything that "belongs" to a user, should either have a ForeignKey or ManyToManyField (depending on whether the object is owned by one user or many) to User on it. Then you can either filter the model based on the User:
SomeModel.objects.filter(user=some_user)
# where `user` is the name of your foreign key field
Or you can access the model through the user via reverse relations, for example:
class SomeModel(models.Model):
...
user = models.ForeignKey(User)
# Later ...
some_user.somemodel_set.all()
The second method is more typical since you generally have the user already from the request, so in your view, you'd just do:
somemodels = request.user.somemodel_set.all()
To get all the SomeModels that belong to the currently logged-in user.

Setting the value of a model field based on user authentication in Django

I'm trying to selectively process a field in my Django/Python application based on whether a user is logged in or not. Basically, I have a model similar to the following:
class Resource(models.Model):
uploaded = models.DateTimeField()
name = models.CharField(max_length=200)
description = models.CharField(max_length=500, blank=True)
file = models.CharField(max_length=200)
What I want to do is for the file attribute to be set to one value if the user happens to be logged in (and has access to this resource based on a test against some permissions backend), and another value if the user is not logged in. So, when any client code tries to access Resource.file, it will get something like the following if the user is not logged in 'http://mysite.com/dummy_resource_for_people_without_access'. However, if the user is logged in and passes some tests for permissions, then the value of resource.file will actually be the true url of that resource (including any security keys etc. to access that resource).
From what I've read, it seems that you can only take account of the currently logged in user by passing that through the request context from a view function to the model. However, in the above use case I am trying to control the access more closely in the model without needing the client code to call a special function.
Your best bet is to create a function used to access the file attribute, and check there. In general, it would possible to turn the attribute into a descriptor which does it implicitly, but Django's metaclass magic would impede that.
In general however, Django is designed to handle authentication at the view-level (and does it very cleanly). If you need database layer authentication, consider a different setup, such as CouchDB.
Just in case anyone's interested, I solved the above issue by actually creating a custom model field in django that could then have a method that takes a user to generate a URI. So, in the database, I store a key to the resource as above in the file column. However, now the file column is some custom field:
class CustomFileField(models.CharField):
def to_python(self, value):
...
return CustomFileResource(value)
class CustomFileResource:
def __init__(self, *args, **kwargs):
....
def uri(usr):
#this method then gets the uri selectively based on the user .
The pattern above is nice because I can wrap the db field and then create a specific method for getting the uri based on who is trying to access it.

Django UserProfile... without a password

I'd like to create a subset of Users that don't have a login... basically as a way to add a photographer field to photos without having a full blown account associated with that person (since in many cases, they'll never actually log in to the site). A caveat is that I'd also like to be able to enable an account for them later.
So, I think the question becomes what's the best way to set up a "People" table that ties to the User table without actually extending the User table with UserProfile.
A user profile (as returned by django.contrib.auth.models.User.get_profile) doesn't extend the User table - the model you specify as the profile model with the AUTH_PROFILE_MODULE setting is just a model which has a ForeignKey to User. get_profile and the setting are really just a convenience API for accessing an instance of a specific model which has a ForeignKey to a specific User instance.
As such, one option is to create a profile model in which the ForeignKey to User can be null and associate your Photo model with this profile model instead of the User model. This would allow you to create a profile for a non-existent user and attach a registered User to the profile at a later date.
Users that can't login? Just given them a totally random password.
import random
user.set_password( str(random.random()) )
They'll never be able to log on.
Supply your own authentication routine, then you can check (or not check) anything you like. We do this so if they fail on normal username, we can also let them in on email/password (although that's not what I'm showing below).
in settings.py:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'userprofile.my_authenticate.MyLoginBackend', # if they fail the normal test
)
in userprofile/my_authenticate.py:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
class MyLoginBackend(ModelBackend):
"""Return User record if username + (some test) is valid.
Return None if no match.
"""
def authenticate(self, username=None, password=None, request=None):
try:
user = User.objects.get(username=username)
# plus any other test of User/UserProfile, etc.
return user # indicates success
except User.DoesNotExist:
return None
# authenticate
# class MyLoginBackend
From the documentation on django auth, if you want to use the User model, it's mandatory to have a username and password, there are no "anonymous accounts". I guess you could create accounts with a default password and then give the opportunity for people to enable a "real" account (by setting a password themselves).
To set up a "People" table that ties to the User table you just have to use a ForeignKey field (that's actually the recommended way of adding additional info to the User model, and not inheritance)
Using a model with a ForeignKey field linking to User might not work as you want because you need anonymous access. I'm not sure if that's going to work, but you might try what happens if you let it have a ForeignKey to AnonymousUser (whose id is always None!) instead.
If you try it, post your results here, I'd be curious.
The django.contrib.auth.models.User exists solely for the purpose of using default authentication backend (database-based). If you write your own backend, you can make some accounts passwordless, while keeping normal accounts with passwords. Django documentation has a chapter on this.
Another upvote for insin's answer: handle this through a UserProfile. James Bennett has a great article about extending django.contrib.auth.models.User. He walks through a couple methods, explains their pros/cons and lands on the UserProfile way as ideal.

Categories

Resources