I have been dealing for a while with Django's authentication system and I just cannot understand why I have to go through this process Django doc! :
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User)
department = models.CharField(max_length=100)
... rather than simply extending the "User" class like this:
class Employee(User):
....
... and re-using all the code contained within. I have taken a look at articles like: b-list.org! , and I understand that the problem may be related with the automatic Django database management.
Is there a way in which I can automatically extend the User model without having to create an additional table in the database, so that Django modifies the current database table for me?
I tend to obey the fellas of the django
https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#extending-the-existing-user-model
Because only abstract models don't create tables in django and built-in user model is not
Related
I have CustomUser model and Post model. I consider adding a lightweight like mechanism to the posts.
What comes to my mind is defining a Like model in such fashion to connect the models to each other:
class LikeFeedback(models.Model):
likingUser = models.ForeignKey(CustomUser)
post_liked = models.ManyToManyField(Post)
But this design produces a new row in the database with each like.
Another option is to define CustomUser and Post models in a way that:
class Post(models.Model):
...
users_liked = models.ManyToManyField(CustomUser)
class CustomUser(models.Model):
...
posts_liked = models.ManyToManyField(Post)
I am not sure if this approach creates a new row or uses a different indexing mechanism, but it looks tidier.
In terms of DB performance what approach is the fastest? Do I need to define the ManyToMany connection in both models to speed up DB processes? Because 15 posts are to be displayed on the webpage at once and and with every post it is necessary to check if the visitor already liked the note. Also, with each like and takeback a write operation is to be performed on the DB.
I am not sure if this approach creates a new row or uses a different indexing mechanism, but it looks tidier.
A ManyToManyField will create an extra table called a junction table [wiki] with ForeignKeys to the model where you define the ManyToManyField, and the model that you target with the ManyToManyField.
You furthermore only need one ManyToManyField, otherwise you make two relations that act indepdently. You thus model this as:
from django.conf import settings
class Post(models.Model):
# ...
likes = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='liked_posts'
)
class CustomUser(models.Model):
# ...
# no ManyToManyField to Post
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I'd like to create a project for finding mentor.
In planning i thought, that it would be nice to separate two models on registration users: for students (those, who wants to find mentor) and mentors.
Built-in django user model isn't like that. I plan to add more fields, also several fields can be the same: in students and in mentors.
Can you give me live example of customing model? Would be nice, if you have smth in git or other code sharing.
Shoudl I inherit mentor model from students, because it can have same fields: email, name, surname, etc?
What additional code should i write for working custom model? I read docs and found unknown for me - managers. Should i also customize managers?
If i get success in custom model what problems can i meet in future for auth,registration, changing passwords for this custom model?
Creating 2 separate models is not recommended here. You will need to have separate login process and be careful to avoid problems with sharing pk between users in separate tables. Also I'm pretty sure that django won't allow that.
Better choice is to make 2 profile models, as described in Extending the existing User model. In one of profiles you will store specific data for student and in other specific data for mentors.
Your website has two intended users, so there is no problem with creating two user models. Just make sure to inherit them from user model
from django.contrib.auth.models import User
class Student(User):
...
class Mentor(User):
...
You shouldn't re-invent the wheel, except you really want to learn and practice core features of Django. Just add some add-on library like userena, which "supplies you with signup, signin, account editing, privacy settings and private messaging". In general userena gives an additional UserenaBaseProfile model which is connected to built-in User model. So you can just inherit this model for the Student and for the Mentor:
from django.contrib.auth.models import User
from userena.models import UserenaBaseProfile
class CustomProfile(UserenaBaseProfile):
user = models.OneToOneField(User, unique=True)
common_field_for_all_children = models.IntegerField()
class Meta:
abstract = True
class Student(CustomProfile):
something_student_related = models.IntegerField()
class Mentor(CustomProfile):
something_mentor_related = models.CharField(max_length=255)
I want to create multiple users in django. I want to know which method will be the best..
class Teachers(models.Model):
user = models.ForeignKey(User)
is_teacher = models.BooleanField(default=True)
.......
or should I use..
class Teacher(User):
is_teacher = models.BooleanField(default=True)
.......
or I have to make custom user model...
Which will be good on creating multiple type users...??
Django doesn't have multiple users - it only has one user and then based on permissions users can do different things.
So, to start off with - there is only one user type in django. If you use the default authentication framework, the model for this user is called User, from django.contrib.auth.models.
If you want to customize user behavior in django, there are three things you can do:
Customize how you authenticate them. By default, authentication is done using a database where passwords are stored. You can authenticate against facebook/google etc. or against your existing user database - for example, with ActiveDirectory if you are on a Windows network.
Create custom permissions, and based on these permissions, restrict what functions users can execute. By default, on every model - django will add basic permissions "can edit", "can delete", "can read". You can create your own and then check if the user has these specific permissions.
You can store extra information about the user, along with whatever normally is stored by django. There are two ways to do this, depending on how much customization you need. If everything django provides by default works for you, and all you want to do is store extra information about the user you can extend the user model - in previous versions this was called creating a custom profile. The other option you have is to create your own User model, if you want deeper customization. The most common use of a custom user model is if you want to use an email address as the username.
You don't have to do all three, in fact sometimes all you want to do is store some extra information or have them authenticate using their email address; in some applications you have to modify all three places.
In your case, since all you want to do is store extra information about a user, you would need to extend the user model, by creating a model that references User (note: you don't inherit from User):
class Profile(models.Model):
user = models.OneToOneField(User)
department = models.CharField(max_length=200, default='Computer Science')
is_teacher = models.BooleanField(default=False)
is_student = models.BooleanField(default=True)
# .. etc. etc.
One approach I was following with Django 1.7 (works with 1.6 too) is to subclass AbstractUser
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
balance = models.DecimalField(default=0.0, decimal_places=2, max_digits=5)
To use your model you need to set it to be the one used for authentication in settings.py:
AUTH_USER_MODEL = 'your_app.User'
Also note that you will now have to use settings.AUTH_USER_MODEL when referencing
your new User model in a relation in your models.
from django.db import models
from django.conf import settings
class Transaction(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL) # ForeignKey(User) will not work
I am currently working on a django application and I am trying to develop a little recommendation system for it. I already extended the User model and made a user profile in an app called profile like so:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
skills = models.CharField(max_length=150)
skillsNeeded = models.CharField(max_length=150)
bio = models.CharField(max_length=300)
industry = models.CharField(max_length=70)
occupation = models.CharField(max_length=70)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
However now I made a separate app within the same Django project called matches and I was wondering how I could pull the current user's data from their profile as well as getting a list of every other user that is in the database. I am using postgresql as my database management system, any ideas or help would be much appreciated. I would think I would need to find out where the profile data is stored in the database and make manual sql queries. However, I am still relatively new to django and this is my first time using postgre for dbms instead of mysql.
Manual SQL queries are almost never necessary. It sounds to me like you just need to use the data models in their basic form to do queries. For example, the current user is available in your views as request.user, so you could get their profile like so:
UserProfile.objects.get(user = request.user)
And getting all of the users is as easy as:
User.objects.all()
I think there is a slight confusion here. Apps in Django are just a heavy-sounding name for a module. Usually, all of your different "apps" will share the same database and can and should import other apps' models to get their work done.
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/