Hello I'm trying to restrict my users to have edu emails. I'm using django 1.10 on python 2.7 and Django-registration-redux. I've seen answers like this one but it requires editing the package directly. This seems like a bad idea? I'm using django-custom-user to use the email as a username, and i have extended the user model like so:
models.py
class CustomEmailUser(AbstractEmailUser):
'''
These are inherited from AbstractEmailUser:
id = models.AutoField(primary_key=True) #this is always present, its a django default
email = models.CharField(unique=True, max_length=255)
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
is_superuser = models.BooleanField()
is_staff = models.BooleanField()
is_active = models.BooleanField()
date_joined = models.DateTimeField()
'''
first_name = models.CharField(max_length=50, default='')
last_name = models.CharField(max_length=50, default='')
All the forms are taken care of by these two packages (which is great!) but i'd like to restrict the email domains to .edu and I'm unsure of how to do this without editing the packages directly. Any suggestions? Thanks!
Related
I have the following custom user model arrangement.
```
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
class StudentProfile(models.Model):
student = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
location = models.CharField(max_length=8, blank=False, default='')
class TeacherProfile(models.Model):
teacher = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
location = models.CharField(max_length=8, blank=False, default='')
gender = models.CharField(max_length=8, choices=GENDER_CHOICES, default='')
```
I am able to a query the students based on the location of their teacher (current user).
Student.objects.filter(location=request.user.teacher.location)
I can also query the user model & find all teachers/students
User.objects.filter(is_teacher=True)
QUESTION:
Without relying on the profile models (Student & Teacher) How can I extend the query on abstractuser using profile attributes.
[X]-This is wrong but the idea is something like;
User.objects.filter(is_teacher=True).filter(is_teacher.location=newyork)
You can follow the OneToOneField in reverse:
User.objects.filter(teacherprofile__location='newyork')
You thus do not need to store is_teacher and is_student explicitly. You can simply filter Students with:
# Users with a related StudentProfile record
User.objects.filter(studentprofile__isnull=False)
i am trying to filter a data set based on a custom user model and having some difficulty with the data.
Basically, i have a registration form in which i am making user select the company they are associated with. So i have created a custom user model with a foreign key association to the company table.
Now, i am trying to query a second dataset so when user logs in, the application looks up the users company association and filters the data to only show results that are associated to the user's company choice.
any suggestion on how i can do this?
my user model is below:
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
the table that i am trying to query on has model below:
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete= models.SET_NULL, null=True)
product = models.ForeignKey(Product, on_delete= models.SET_NULL, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
requestorname = models.CharField(max_length=100, null=True)
requestorage = models.CharField(max_length=2,null=True, blank=True)
child_id = models.ForeignKey(ChildID, on_delete=models.SET_NULL, null=True, blank=True)
comments = models.CharField(max_length=100,null=True, blank=True)
requestdate_create = models.DateTimeField(auto_now_add=True)
note that both table has association to customer table using a foriegn key, so i want the user to only see the order associated to the company he/she belongs to.
appreciate any directions to help write the view. Thanks
So I was able to solve my own problem. I had to pass the request in as an argument. posting it here so folks with the same question can find answer. the view goes something like this.
def externalrequest(request):
args = request.user.customer_id
external = Order.objects.filter(customer=args)
context = {'external':external}
return render(request, 'accounts/external.html', context)
This question already has an answer here:
How to query related models in django models.py
(1 answer)
Closed 3 years ago.
I have a model called StudentProfile:
class StudentProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
class_advisor = models.CharField(max_length=50)
year = models.OneToOneField(YearLevel, on_delete=models.SET_NULL, null=True)
section = models.OneToOneField(Section, on_delete=models.SET_NULL, null=True)
what I want to happen is, class_advisor to only return and accpet User with is_teacher = True.
by the way here's my User model:
class User(AbstractUser):
email = models.EmailField(
max_length=254,
unique=True,
verbose_name='Email Address',
blank=True
)
is_student = models.BooleanField(default=False, verbose_name='Student')
is_superuser = models.BooleanField(default=False, verbose_name='Administrator')
is_teacher = models.BooleanField(default=False, verbose_name='Teacher')
is_staff = models.BooleanField(default=False, verbose_name='Staff')
is_registrar = models.BooleanField(default=False, verbose_name='Registrar')
Yes, however at the moment, something is wrong with your modeling. You should make class_advisor a ForeignKey to the user model. Imagine that you store the username (or whatever unique attribute of that user) in your model. If later that teacher changes that username, then it will refer to a non-existing user, or later to a different user that picked the username.
You can set the limit_choices_to=... parameter [Django-doc]:
from django.db.models import Q
from django.contrib.auth import get_user_model
class StudentProfile(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, primary_key=True, related_name='studentprofile')
class_advisor = models.ForeignKey(get_user_model(), limit_choices_to=Q(is_teacher=True), related_name='students')
year = models.OneToOneField(YearLevel, on_delete=models.SET_NULL, null=True)
section = models.OneToOneField(Section, on_delete=models.SET_NULL, null=True)
If you use forms, etc. It will limit the options to Users that are teachers, and do validation on this.
It is better to use get_user_model() [Django-doc] here to refer to your user model, since if you later alter it, the ForeignKey (and OneToOneField will refer to the new model).
Try this:
StudentProfile.objects.filter(user__is_teacher=True)
StudentProfile.objects.filter(user__is_teacher=True).values('class_advisor')
I want to create two users with these details.
class Doctor(models.Model):
username = models.CharField(max_length=500)
password = models.CharField(max_length=500, null=True)
gender = models.CharField(choices=GENDER_CHOICES, max_length=128)
specialties = models.CharField(max_length=1000)
education = models.CharField(max_length=1000)
hospitals = models.CharField(max_length=1000)
rate = models.FloatField()
email = models.EmailField(unique=True)
description = models.TextField(null=True)
class Patient(models.Model):
username = models.CharField(max_length=500)
password = models.CharField(max_length=500, null=True)
email = models.EmailField(unique=True)
gender = models.CharField(choices=GENDER_CHOICES, max_length=128)
age = models.IntegerField()
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
I'm starting to use this approach either, and judging for the time your question have here, it is very probable that you already figured this out, but I want to answer this since I was looking for an answer not that long ago, and maybe this could help others.
Anyway, I was previously using the 'profile like' way before this AbstractUser one, but in your answer I see them both mixed, in your patient model you're using a OneToOne FK to the original auth_user model, but you're asking for the AbstractUser.
So just in case you're looking for the 'Profile like' which is really called 'proxy model' option, you're already almost done, you would just need to add a OneToOne field to the User as in your Patient model but in the Doctor model, and then you would have two models with extra information, but nothing to do with login, access or permissions, just for profile, ready to go.
The docs on the following link explain this
Proxy model basic documentation
Now if what you're looking for is to use the other way, substituting the user model, for which you need the AbstractUser, what you need to do (or better stated, what you could do, which is what I'm doing now) is to create a base custom user class.
Which you can see a full example in the documentation
In your case
class MyBaseUser(AbstractUser):
username = models.CharField(max_length=500)
password = models.CharField(max_length=500, null=True)
email = models.EmailField(unique=True)
gender = models.CharField(choices=GENDER_CHOICES, max_length=128)
class Doctor(MyBaseUser):
specialties = models.CharField(max_length=1000)
education = models.CharField(max_length=1000)
hospitals = models.CharField(max_length=1000)
rate = models.FloatField()
description = models.TextField(null=True)
class Patient(MyBaseUser):
age = models.IntegerField()
Now, remember that you need to specify in the settings the AUTH_USER_MODEL, you could follow a cookiecutter template so all of this would be pre-formatted.
Also, you can add your USERNAME_FIELD within your MyBaseUser class to state which field would be used as login username, as well as the REQUIRED_FIELDS in the same class.
Have a nice one, as our friend Destin likes to say.
I have followed these [1,2,3] links to create a custom user model by extending AbstractBaseUser class. I am storing login information of three type of users lets say teacher, Admin and students in this table. USERNAME field is emailId.
I want to make emailId unique among one type of users. In other words, in my system student can register as teacher as well with same emailId. But since emailId is USERNAME field and hence unique, I am unable to achieve this.
Please suggest how can I do this in Django application.
UserModel :
class UserModel(AbstractBaseUser):
user_type_choices = (
(constants.USER_TYPE_ADMIN, 'Admin'),
(constants.USER_TYPE_INSTITUTE, 'Institute'),
(constants.USER_TYPE_STUDENT, 'Student')
)
sys_id = models.AutoField(primary_key=True, blank=True)
name = models.CharField(max_length=127, null=False, blank=False)
email = models.EmailField(max_length=127, unique=True, null=False, blank=False)
mobile = models.CharField(max_length=10, unique=True, null=False, blank=False)
user_type = models.PositiveSmallIntegerField(choices=user_type_choices, null=False, blank=True)
is_staff = models.BooleanField()
is_active = models.BooleanField(default=True)
objects = MyUserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ['name', 'mobile', 'user_type','is_staff']
I am using other models like StudentsDetails, TeacherDetails with foreign key to UserModel to store extra information.