how to use custom user model for django-graphql-auth - django

I am using graphql in my project and want to generate token while registration. Even though django-graphql-auth has all the written mutation, it uses a different user model. But I want to use my custom user model. What should I do?
This is my user model
class CustomUser(AbstractUser):
"""
Customized User Model
"""
email = models.EmailField(blank=True, null=True,
max_length=256, unique=True)
mobile_no = models.CharField(
max_length=20, blank=True, null=True, unique=True)
verification_code = models.CharField(max_length=6)
code_valid_till = models.DateTimeField(blank=True, null=True)
timezone = models.CharField(max_length=40, blank=True, null=True)
country = models.CharField(max_length=20, default='BD', choices=COUNTRIES)
pin_verified = models.BooleanField(default=False)
email_verified = models.BooleanField(default=False)
modified_on = models.DateTimeField('date modified', auto_now=True)
created_on = models.DateTimeField(auto_now_add=True)
# For password reset
reset_verification_code = models.CharField(
max_length=6, blank=True, null=True)
reset_code_valid_till = models.DateTimeField(blank=True, null=True)
reset_request = models.BooleanField(default=False)
reset_valid_till = models.DateTimeField(blank=True, null=True)
class Meta:
verbose_name_plural = "User"
def __str__(self):
if not self.is_anonymous:
return "{} - {}".format(self.mobile_no, self.email)
else:
return "Anon"
#property
def get_full_name(self):
return super().get_full_name()
def get_all_permissions(self, obj=None):
return super().get_all_permissions(obj=obj)
def send_email(self, subject, message, to_email: list, from_email=None, **kwargs):
send_mail_to_user(subject, message, from_email, to_email, **kwargs)

I'm the author of the package. Now the documentation site has a custom user model in the quickstart, you can see it here. Currently, it's not documented how to use it with a custom user model, but it is already an open issue, you can see it here. I will paste the same answer that is on the Github.
From Django docs:
Changing to a custom user model mid-project
Changing AUTH_USER_MODEL after you’ve created database tables is
significantly more difficult since it affects foreign keys and
many-to-many relationships, for example.
So, make sure to create the custom user model when you start your project.
Add the following to your custom user model
Following the Django custom user model.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
# ...
USERNAME_FIELD = "<username_filed_name>" # e.g: "username", "email"
EMAIL_FIELD = "<email_field_name>" # e.g: "email", "primary_email"
Add your custom user model in the settings
See here for more info.
# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
Please let me know if you have further questions :)
Edit: Add the mobile_no in the registration
Use the REGISTER_MUTATION_FIELDS or REGISTER_MUTATION_FIELDS_OPTIONAL.
# settings.py
GRAPHQL_AUTH = {
# ...
REGISTER_MUTATION_FIELDS = [
# ...
'mobile_no'
]
# or
REGISTER_MUTATION_FIELDS_OPTIONAL = ['mobile_no']
# You can set the graphene base scalars:
REGISTER_MUTATION_FIELDS = {
"email": "String",
"username": "String",
"mobile_no": "String",
}
}

Related

"unique = True" - Django models - Unique for each user not unique for all data submitted by everyone

I have a models in Django currently and I have made a field unique=True so that no duplicates are submitted to the database. My problem is that it extends to all users. By this I mean that User 1 should be able to submit "Example1" and "Example2" and should never be able to submit "Example1" or "Example2" again and then User2 should come along and also be able to submit "Example1" and "Example2" but they cant because User 1 already submitted it. Is there a way where I can get somewhat of a unique=True but separately for each user and not just conjoined like it is now.
Thanks in advance. Code Below.
The problem resides in type = and my users are being defined by ForeignKey also.
class Field_Repo1(models.Model):
user = models.ForeignKey(User, default=True, related_name="Field_Repo1", on_delete=models.PROTECT)
title = models.CharField(max_length=20, verbose_name='Title of Field')
type = models.CharField(max_length=200, blank=True, unique=True, null=True, verbose_name='Field')
class Meta:
ordering = ['-type']
def __str__(self):
return str(self.user) or 'NONE'
def get_absolute_url(self):
return reverse('repo1')
UPDATED CODE THAT WORKS
class Field_Repo1(models.Model):
user = models.ForeignKey(User, default=True, related_name="Field_Repo1", on_delete=models.PROTECT)
title = models.CharField(max_length=20, verbose_name='Title of Field')
type = models.CharField(max_length=22, choices=FIELDS, verbose_name='Field')
class Meta:
ordering = ['-type']
constraints = [
models.UniqueConstraint(fields=['user', 'type'], name='unique type for each user')
]
def __str__(self):
return str(self.user) or 'NONE'
def get_absolute_url(self):
return reverse('repo1')
You need to use UniqueConstraint:
class Field_Repo1(models.Model):
user = models.ForeignKey(User, default=True, related_name="Field_Repo1", on_delete=models.PROTECT)
title = models.CharField(max_length=20, verbose_name='Title of Field')
type = models.CharField(max_length=200, blank=True, unique=True, null=True, verbose_name='Field')
def __str__(self):
return str(self.user) or 'NONE'
def get_absolute_url(self):
return reverse('repo1')
class Meta:
ordering = ['-type']
constraints = [
models.UniqueConstraint(fields=['user', 'title'], name='unique title for each user')
]

Get All Changes of Any registered model of a single user django-simple-history

# settings.py
INSTALLED_APPS = [
# ...
'simple_history',
# ...
]
MIDDLEWARE = [
# ...
'simple_history.middleware.HistoryRequestMiddleware',
# ...
]
Models:
from django.db import models
from apps.companies.models import Company
from simple_history.models import HistoricalRecords
# Create your models here.
class User(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=20)
history = HistoricalRecords()
class Contact(TimeStamp):
name = models.CharField(max_length=100, verbose_name='Person Name')
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
phone_number = models.CharField(max_length=100, verbose_name='Personal Number', null=True, blank=True)
email = models.EmailField(null=True, blank=True, verbose_name='Personal Email')
designation = models.CharField(max_length=100)
history = HistoricalRecords()
def __str__(self):
return self.name
user = User.objects.first()
is there anyway to get all changes any model by the user
Your question seems similar than this issue on the django-simple-history repository : https://github.com/jazzband/django-simple-history/issues/684
You'd have to query each historical model since they're all in
separate tables. You could build a way to automatically detect which
models are historical and get them though.

How to access reverse relationship in django models?

I have two models one for User and another for storing CustomerInfo(user of type customer).
class User(AbstractBaseUser):
"""
This is a class for user table which overrides functionalities of default django user model.
Attributes:
name (CharField): Name of a user.
email (EmailField): Email address of a user.
mobile (CharField): Phone number of a user.
date_joined (CharField): When a user was added.
last_login (CharField): Last login date time of a user.
is_admin (CharField): If user is a admin or not.
is_active (CharField): If user is active or not.
is_staff (CharField): If user is staff or not.
is_superuser (CharField): If user is a superuser or not.
role (OneToOneField): One to one relationship with role table.
"""
name = models.CharField(max_length=80)
email = models.EmailField(max_length=255, unique=True)
mobile = models.CharField(
validators=[
RegexValidator(
regex=r"^\d{10,14}$",
message="Phone number must be entered in format: '+999999999'. Up to 14 digits allowed.",
)
],
max_length=15,
unique=True,
)
role = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True)
drivers = models.ManyToManyField(
"self", through="DispatcherDriver", symmetrical=False
)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
USERNAME_FIELD = "mobile"
REQUIRED_FIELDS = ["email", "name"]
objects = UserManager()
class Meta:
db_table = "users"
def __str__(self):
return self.name
# For checking permissions. to keep it simple all admin have ALL permissons
def has_perm(self, perm, obj=None):
return self.is_admin
# Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)
def has_module_perms(self, app_label):
return True
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class CustomerInfo(models.Model):
customer = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True, related_name="customer_info"
)
company_name = models.CharField(max_length=255)
class Meta:
db_table = "customer_info"
def __str__(self):
return self.company_name
CustomerInfo model has OneToOneField mentioned in the model. How can I access CustomerInfo of a User model using reverse relationship?
Suppose, you has User's instance user then you can fetch customer_info as
from django.core.exceptions import ObjectDoesNotExist
try:
customer_info = user.customer_info
except ObjectDoesNotExist:
print("There is no customer info here.")
Reference - https://docs.djangoproject.com/en/3.1/topics/db/examples/one_to_one/
Try:
myuser = User.objects.create(email="..", name="..", password="1223")
profile = CustomerInfo.objects.create(customer=myuser)
company_name = myuser.customer_info.company_name

Use django-reviews package with an app which uses customized user model

I am working on a django App where I am using a custom user models for AUTH_USER_MODEL i.e AUTH_USER_MODEL = 'account.User'I extended the AbstractBaseUser class to create my model that is like
class User(AbstractBaseUser):
is_provider = models.BooleanField(_('Provider status'), default=False)
USERNAME_FIELD = 'email'
..........
In my settings.py file i added AUTH_USER_MODEL = 'account.User' means now my User model is accounts.User not django.contrib.auth.User.
I want to add django-reviews app app im my webapp to get the reviews but the problem is django-reviews used DJango.contrib.auth.User as its default AUTH_USER_MODEL.
class Review(models.Model):
"""A ``Review`` consists on a comment and a rating.
"""
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="content_type_set_for_%(class)s")
content_id = models.PositiveIntegerField(_(u"Content ID"), blank=True, null=True)
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
# if the user is authenticated we save the user otherwise the name and the
# email.
user = models.ForeignKey(User, verbose_name=_(u"User"), blank=True, null=True, related_name="%(class)s_comments")
session_id = models.CharField(_(u"Session ID"), blank=True, max_length=50)
user_name = models.CharField(_(u"Name"), max_length=50, blank=True)
user_email = models.EmailField(_(u"E-mail"), blank=True)
comment = models.TextField(_(u"Comment"), blank=True)
score = models.FloatField(_(u"Score"), choices=SCORE_CHOICES, default=3.0)
active = models.BooleanField(_(u"Active"), default=False)
creation_date = models.DateTimeField(_(u"Creation date"), auto_now_add=True)
ip_address = models.IPAddressField(_(u"IP address"), blank=True, null=True)
now it is giving me error
File "/home/user/dir/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 314, in validate
raise CommandError("One or more models did not validate:\n%s" % error_text)
django.core.management.base.CommandError: One or more models did not validate:
reviews.review: 'user' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
Tell me a way that how can i use the django-reviews with my app while not using the default auth model as my AUTH_USER_MODEL.

Django Server Killed

I am running Django 1.6 with a custom user model. The user model inherits AbstractBaseUser, PermissionsMixin and works fine. It let's me call login() and authenticate() and when I do syncdb it creates it with no errors and will allow me to create a superuser in the command line interface.
I am trying to use the Django admin panel. I can access /admin/ fine and login and it will display the list of registered models.
I can modify all models, with the exception of "user". I can click the "user" model and see a list of users, however if I try and add a new user or edit an existing user, the request will take approximately 1 minute and then the django web server will exit with the message "Killed".
I would post some code however I have no idea what would be relevant because the error is so vague.
Is there another error log somewhere I can find out more details?
Edit:
Custom user model code:
class User(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True)
full_name = models.CharField("Full Name", max_length=100)
email_address = models.CharField(max_length=255, unique=True, db_index=True)
company_name = models.CharField(max_length=50, blank=True, null=True)
time_zone = models.CharField(max_length=50, blank=True, null=True)
activation_key = models.CharField(unique=True, max_length=50, blank=True, null=True)
location = models.ForeignKey(Location, related_name='fk_user_2_country', blank=True, null=True)
username = models.CharField(max_length=20, blank=True, null=True, unique=True)
is_staff = models.BooleanField(default=False)
class Meta:
db_table = 'user'
USERNAME_FIELD = 'email_address'
objects = UserManager()
REQUIRED_FIELDS = ['full_name',]
def get_full_name(self):
return self.email_address
def get_short_name(self):
return self.email_address
def activate_email(self, activation_key):
if self.activation_key == activation_key:
self.activation_key = None
self.save()
return True
else:
return False
def __unique__(self):
return self.email_address
def is_active(self):
return self.activation_key is None
This was caused by the relationship to the "Location" table location = models.ForeignKey(Location, related_name='fk_user_2_country', blank=True, null=True).
This table contained 3.3 Million rows, the Django admin panel was trying to list them all and as a result was crashing.