I have made a custom profile model which looks like this:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey('User', unique=True)
name = models.CharField(max_length=30)
occupation = models.CharField(max_length=50)
city = models.CharField(max_length=30)
province = models.CharField(max_length=50)
sex = models.CharField(max_length=1)
But when I run manage.py syncdb, I get:
myapp.userprofile: 'user' has a relation with model User, which has
either not been installed or is abstract.
I also tried:
from django.contrib.auth.models import BaseUserManager, AbstractUser
But it gives the same error. Where I'm wrong and how to fix this?
Exactly in Django 1.5 the AUTH_USER_MODEL setting was introduced, allowing using a custom user model with auth system.
If you're writing an app that's intended to work with projects on Django 1.5 through 1.10 and later, this is the proper way to reference user model (which can now be different from django.contrib.auth.models.User):
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
See docs for more details.
In case you're writing a reusable app supporting Django 1.4 as well, then you should probably determine what reference to use by checking Django version, perhaps like this:
import django
from django.conf import settings
from django.db import models
def get_user_model_fk_ref():
if django.VERSION[:2] >= (1, 5):
return settings.AUTH_USER_MODEL
else:
return 'auth.User'
class UserProfile(models.Model):
user = models.ForeignKey(get_user_model_fk_ref())
Change this:
user = models.ForeignKey('User', unique=True)
to this:
user = models.ForeignKey(User, unique=True)
Related
how to make models for user auth(use abstract user) for login and signup using Django?
I want to make login OTP based for ecommerse website.
from django.db import models
class User(models.Model):
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=40)
mobile = models.CharField(max_length=10)
address = models.CharField(max_length=200)
emailId = models.CharField(max_length=50)
password = models.CharField(max_length=200)
I tr above code.
What should I have to add above?
You should use AbstractUser if you want to inherit permissions settings and all functions that Django uses.
In settings, you should also add AUTH_USER_MODEL = "your_module_name.User"
In Django, making a user model by yourself is not recommended because other 3rd party packages depend on the user models Django provided.
There are two ways you can follow.
Extending the existing User model
Using a custom user model when starting a project
I wanted to make a Django authentication but I was confused about wichone is better?
is it is better to edit the venv/Lib/site-packages/django/contrib/auth/forms.py file and make my custom form and edit DB on venv/Lib/site-packages/django/contrib/auth/models.py or it's better to make my authentication system with model and views and forms on my application?
You don't need to add django's files. you can inherit there properties.
for example let's say you want to use User model of Django. you can do that in your models.py like following. here you ll get all the fields of Abstract User like first_name, email, passwords etc but you can add your own fields such as technoking in below example
from django.db import models
from django.contrib.auth.models import AbstractUser
import uuid
class User(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
technoking = models.BooleanField(default=False)
objects = UserManager()
def __str__(self):
return self.username
I am writing a webapp where I want to have a general Person table to uniquely identify any person interacting with the website, e.g. to be able to comply to GDPR requests.
Some Persons will should also be Users in the authentication sense.
I'd like to use Person.email for the username.
However, I cannot manage to make authentication / admin interface work.
Simplified models:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class Person(models.Model):
name = models.CharField(max_length=255, blank=False)
email = models.EmailField(blank=False, unique=True)
class User(AbstractBaseUser, PermissionsMixin):
person = models.OneToOneField(Person, on_delete=models.PROTECT)
USERNAME_FIELD = ...# what to put here?
I found a very old Django issue that seems related:
https://code.djangoproject.com/ticket/21832
Any idea, how to make this work with a foreign key to hold the basic user information?
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
Here you go for correct way of achieving this
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
USERNAME_FIELD = ['email'] # It's mean you can login with your email
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Note: If you use AbstractBaseUser models, then you have to write custom model manager.
To avoid writing custom models manager, you should use AbstractUser
class User(AbstractUser):
pass
# here all the required fields like email, name etc item
You can create Person record for the user when a user records creating using django signal:
https://docs.djangoproject.com/en/3.2/topics/signals/
I'm getting this error.
ERRORS: subscriptions.StripeCustomer.user: (fields.E301) Field defines
a relation with the model 'auth.User', which has been swapped out.
HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
I'm trying to configure Django Stripe Subscriptions following this manual https://testdriven.io/blog/django-stripe-subscriptions/
My models.py
from django.contrib.auth.models import User
from django.db import models
class StripeCustomer(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
stripeCustomerId = models.CharField(max_length=255)
stripeSubscriptionId = models.CharField(max_length=255)
def __str__(self):
return self.user.username
My admin.py
from django.contrib import admin
from subscriptions.models import StripeCustomer
admin.site.register(StripeCustomer)
My settings.py
#used for django-allauth
AUTH_USER_MODEL = 'accounts.CustomUser'
DEFAULT_AUTO_FIELD='django.db.models.AutoField'
SITE_ID = 1
AUTHENTICATION_BACKENDS = (
'allauth.account.auth_backends.AuthenticationBackend',
'django.contrib.auth.backends.ModelBackend',
)
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
ACCOUNT_EMAIL_VERIFICATION = "none"
accounts/models.py
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
class Meta:
verbose_name_plural = 'CustomUser'
After setting above, I executed "python manage.py makemigrations && python manage.py migrate" then the error occurred.
I just mentioned the above settings in this question but still if more code is required then tell me I'll update my question with that information. Thank you
You have your OneToOneField pointing to the User model from django.contrib.auth when in fact you are using a custom user model CustomUser, hence you get the error. Generally if one wants to have a foreign key or any related field with the user model one should point it to settings.AUTH_USER_MODEL as described in the Referencing the User model [Django docs] so that such issues can be prevented easily. Hence change your StripeCustomer model like so:
from django.conf import settings
from django.db import models
class StripeCustomer(models.Model):
user = models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stripeCustomerId = models.CharField(max_length=255)
stripeSubscriptionId = models.CharField(max_length=255)
def __str__(self):
return self.user.username
So I'm trying to automatically assign the current logged in user to a variable in my model. I think this make sense but I'm not able to migrate the models and it is going me this error.
models.py:
from django.db import models
from django.contrib.auth.models import User
from datetime import date
# Create your models here.
class UserProfileInfo(models.Model):
user = models.OneToOneField(User)
portfolio_site = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to='profile_pics',blank='True')
def __str__(self):
return self.user.username
class UserPosts(models.Model):
post_title = models.CharField(max_length=100,unique=True)
post_sub_title = models.CharField(max_length=250,unique=False)
post_author = models.ForeignKey('User',User.username)
post_date = models.DateField(default=date.today,blank=True)
post_body = models.TextField(max_length=1000,unique=False)
def __str__(self):
return str(self.post_title)
The Error:
ValueError: Cannot create form field for 'post_author' yet, because its related model 'User' has not been loaded yet
Remove the quotation from this line:
post_author = models.ForeignKey('User',User.username)
It should be like this:
post_author = models.ForeignKey(User,User.username)
I think the problem is this:
from django.contrib.auth.models import User
post_author = models.ForeignKey('User',User.username)
Your ForeignKey want's to use the attribute 'username' of the imported User. Not of your User object when related.
I think I just deleted the migrations and then migrated again from scratch...