Trying to create a simple launch page for my website to collect email addresses. When the user goes to submit, it is providing the following error (traceback below)--Unique Constraint Failed---accounts.user.username. I figured maybe this has to do with the email address entered overlapping with username, but as you can see in my accounts model--the username is created from the email. (Note the entire User and User Profile models are not being utilized throughout my site yet, but just preparing for future usage). Any help is appreciated. Thanks
Traceback (most recent call last):
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\crstu\PycharmProjects\dealmazing\dealmazing\views.py", line 15, in newsletter_signup
instance.save()
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\auth\base_user.py", line 74, in save
super(AbstractBaseUser, self).save(*args, **kwargs)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 708, in save
force_update=force_update, update_fields=update_fields)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 736, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 820, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 859, in _do_insert
using=using, raw=raw)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py", line 1039, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py", line 1060, in execute_sql
cursor.execute(sql, params)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\six.py", line 685, in reraise
raise value.with_traceback(tb)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\sqlite3\base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_user.username
my Accounts app model below:
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
PermissionsMixin
)
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.db.models.signals import post_save
import os
def avatar_upload_path(instance, filename):
return os.path.join('avatars', 'user_{0}', '{1}').format(
instance.user.id, filename)
class UserManager(BaseUserManager):
def create_user(self, email, username=None, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
username = email.split('#')[0]
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email,
username,
password,
)
user.is_staff = True
user.is_superuser = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True, default='')
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return "#{}".format(self.username)
def get_short_name(self):
return self.username
def get_long_name(self):
return "#{} ({})".format(self.username, self.email)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, related_name='profile')
first_name = models.CharField(max_length=40, default='', blank=True)
last_name = models.CharField(max_length=40, default='', blank=True)
bio = models.TextField(blank=True, default='')
avatar = models.ImageField('Avatar picture',
upload_to=avatar_upload_path,
null=True,
blank=True)
def __str__(self):
return self.user.username
#property
def get_avatar_url(self):
if self.avatar:
return '/media/{}'.format(self.avatar)
return 'http://www.gravatar.com/avatar/{}?s=128&d=identicon'.format(
'94d093eda664addd6e450d7e9881bcad'
)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
and here's the view for my actual newsletter that is collecting email address. note i'm just temporarily redirecting to google for now as a test:
from django.shortcuts import render, redirect
from newsletters.forms import NewsletterUserSignUpForm
from accounts.models import User
def newsletter_signup(request):
if request.method == "POST":
form = NewsletterUserSignUpForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
if User.objects.filter(email=instance.email).exists():
print("Sorry this email already exists")
else:
instance.save()
return redirect("http://www.google.com")
else:
form = NewsletterUserSignUpForm()
template = "newsletters/sign_up.html"
return render(request, template, {'form': form})
sign up html form looks like this:
<div class="col-lg-6 offset-lg-3">
<form method="POST">
{% csrf_token %}
<div class="form-group">
<div class="col-xs-6 col-xs-offset-3">
{{ form.email}}
<button class="btn btn-primary" type="submit">Sign Up!</button>
</div>
</div>
</form>
</div>
</div>
Your User model has a username field which requires unique=True which is the cause of your problem. Now you might be having a user having a username field as '' which is default. Since you already have one user with this username you can't have another user with this field. You should check that user already exists in the db or not also you have to enter some username with a user don't use default with unique=True its a really bad design and always fails.
since you are using username = email.split('#')[0] to get the username for the user. It is possible that two different email would give you same value for the username. For example example#abc.com and example#def.com. What you need to do is figure out some other algorithm to set the username or a good idea can be to user the email as username.
In your Accounts app model try this user.save(using=self._db) , this might help you
Related
I am not able to createsuperuser, I am getting the following error
Django Version 3.1.1
Traceback (most recent call last):
File "/Users/napoleon/django-app/mysite/manage.py", line 22, in <module>
main()
File "/Users/napoleon/django-app/mysite/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/core/management/base.py", line 330, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 79, in execute
return super().execute(*args, **options)
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/core/management/base.py", line 371, in execute
output = self.handle(*args, **options)
File "/Users/napoleon/django-app/pfs-venv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 189, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
AttributeError: 'UserManager' object has no attribute 'create_superuser'
basically its throwing
AttributeError: 'UserManager' object has no attribute 'create_superuser'
I read this alsoSO-related question I don't get it exactly as conveyed there.
Custom User models mainapp/models.py
import uuid
from django.contrib.auth.models import AbstractUser, UserManager
from django.db import models
class CustomUserManager(UserManager):
def create_user(self, email,date_of_birth, username,password=None,):
if not email:
msg = 'Users must have an email address'
raise ValueError(msg)
if not username:
msg = 'This username is not valid'
raise ValueError(msg)
# if not date_of_birth:
# msg = 'Please Verify Your DOB'
# raise ValueError(msg)
# user = self.model( email=UserManager.normalize_email(email),
# username=username,date_of_birth=date_of_birth )
user = self.model( email=UserManager.normalize_email(email),
username=username )
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,username,password,date_of_birth):
user = self.create_user(email,password=password,username=username,date_of_birth=date_of_birth)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
# Custom User Model
class User(AbstractUser):
id = models.BigAutoField(primary_key=True)
user_uuid = models.UUIDField(default=uuid.uuid1())
full_name = models.CharField(max_length=200,default='')
email = models.CharField(max_length=200,default='')
#form can have empty value blank=True, db can have empty value null=True
email_last_verified_on = models.DateTimeField(null=True)
Settings.py
# Swapping the user model
AUTH_USER_MODEL = 'mainapp.User'
Please clarify, what am I missing ...
You need to add the UserManager to the User mode:
class User(AbstractUser):
# …
objects = CustomUserManager()
Without specifying the manager, it will fallback to the UserManager [Django-doc], not the CustomUserManager.
I have some troubles with migrating my database in django
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 350, in execute
self.check()
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 379, in check
include_deployment_checks=include_deployment_checks,
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 366, in _run_checks
return checks.run_checks(**kwargs)
File "E:\Env\Python\Python37-32\lib\site-packages\django\core\checks\registry.py", line 71, in run_checks
new_errors = check(app_configs=app_configs)
File "E:\Env\Python\Python37-32\lib\site-packages\django\contrib\auth\checks.py", line 74, in check_user_model
if isinstance(cls().is_anonymous, MethodType):
File "E:\Env\Python\Python37-32\lib\site-packages\django\db\models\base.py", line 470, in __init__
_setattr(self, field.attname, val)
File "E:\Env\Python\Python37-32\lib\site-packages\django\db\models\fields\related_descriptors.py", line 537, in __set__
% self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use username.set() instead.
Here is my models.py:
class PostComments(models.Model):
post = models.ForeignKey(InfoPost, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="username")
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
#approved_comment = models.BooleanField(default=False)
reply_to = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE, related_name='replies')
#def __str__(self): return 'Comment by {} on {}'.format(self.name, self.post)
I am trying to make comments system for post in my website, but there is some error occured. I don't know whats wrong with my model, but if i try to make migrations without my new PostComments model, its migrating pretty fine.
UPD. Here is my code, where i am using my PostComments model
forms.py
class CommentsForm(forms.ModelForm):
post = forms.CharField(required=False)
author = forms.CharField(required=False)
class Meta:
model = PostComments
fields = '__all__'
views.py
def post(request, slug):
post = get_object_or_404(InfoPost, slug=slug)
comment_list = CommentsForm._meta.model.objects.all()
if request.user.is_authenticated:
user = User.objects.get(username=request.user.username)
if request.method == 'POST':
comment = CommentsForm(request.POST)
print(comment.is_valid())
if comment.is_valid():
com = comment.save(commit=False)
com.author = request.user
com.post = post
com.save()
return redirect('post', slug=slug)
else:
comment_form = CommentsForm()
return render_to_response('MainPage/Post.html',
{'post': post, "user": user, 'img_w': image_w, 'img_h': image_h,
'comments_list': comment_list, 'comment_form': comment_form})
return render_to_response('MainPage/Post.html', {'post': post, 'img_w': image_w, 'img_h': image_h, 'comments_list': comment_list})
I was thinking, its started after i tried to get all objects of comments for displaying them in view, but i don't really know
You are shielding the actual username field on the User model with the related_name on the author ForeignKey.
It should be like this:
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="usernames")
'related_name=usernames' at plural.
The reason why it failed is because when you did:
user = User.objects.get(username=request.user.username)
you were basically accessing the reverse relation to the comments set that are tied to the user, not the actual username field (which I assume is a CharField).
More info about related_name in the django documentation.
I don't understand why you have set post and author to CharFields, when the model has foreign keys. Especially as you are setting then directly in the model anyway.
You should remove those definitions, and then exclude the fields from the form altogether:
class CommentsForm(forms.ModelForm):
class Meta:
model = PostComments
exclude = ("post", "author")
models.py
from __future__ import unicode_literals
from django.db.models.signals import post_save
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
class Friend(models.Model):
users = models.ManyToManyField(User)
current_user = models.ForeignKey(User, related_name = 'owner',null=True)
#classmethod
def make_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user = current_user
)
friend.users.add(new_friend)
#classmethod
def lose_friend(cls, current_user, new_friend):
friend, created = cls.objects.get_or_create(
current_user = current_user
)
friend.users.remove(new_friend)
class Post(models.Model):
post=models.CharField(max_length=500)
user=models.ForeignKey(User)
data = models.DateTimeField(auto_now=True)
class UserProfileManager(models.Manager):
def queryset(self):
return super(UserProfileManager,self).get(queryset).filter(city='surat')
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100,default='')
city = models.CharField(max_length=100,default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='profile_image',blank=True)
surat = UserProfileManager()
def __str__(self):
return self.user.username
def create_profile(sender,**kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile,sender=User)
views.py
from django.http import HttpResponse
from django.shortcuts import render,redirect
from django.contrib.auth.forms import UserCreationForm
from tutorial import views
from accounts.forms import Registrationform,EditProfileForm
from django.contrib.auth.forms import UserChangeForm,PasswordChangeForm
from django.contrib.auth.models import User
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from .forms import HomeForm
from .models import Post,Friend
class HomeView(TemplateView):
template_name = 'accounts/home.html'
def get(self,request):
form = HomeForm()
posts=Post.objects.all()
users = User.objects.exclude(id=request.user.id)
friend =Friend.objects.get(current_user=request.user)
friends = friend.users.all()
args={
'form':form,'posts':posts,'users':users,'friends': friends
}
return render(request,self.template_name, args)
def post(self,request):
form = HomeForm(request.POST)
if form.is_valid():
post=form.save(commit=False)
post.user=request.user
post.save()
text =form.cleaned_data['post']
form = HomeForm()
return redirect('accounts:home')
args = {'form' : form,'text' : text}
return render(request, self.template_name,args)
def change_friends(request, operation, pk):
new_friend = User.objects.get(pk=pk)
if operation == 'add':
Friend.make_friend(request.user, new_friend)
elif operation == 'remove':
Friend.lose_friend(request.user, new_friend)
return redirect ('accounts:home')
def register(request):
if request.method == "POST":
form = Registrationform(request.POST)
if form.is_valid():
form.save()
return redirect('/accounts')
else:
return HttpResponse('please fill all the fields and make sure new password must be match')
else:
form = Registrationform()
args={'form' : form}
return render(request,'accounts/reg_form.html',args)
#login_required
def view_profile(request,pk=None):
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
args = {'user' : user}
return render(request,'accounts/profile.html',args)
#login_required
def edit_profile(request):
if request.user.is_authenticated():
#<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
if request.method=="POST":
form = EditProfileForm(request.POST,instance=request.user)
if form.is_valid():
form.save()
return redirect('/accounts/profile')
else:
return HttpResponse("please go back and write correct values")
else:
form = EditProfileForm(instance=request.user)
args = {'form' : form}
return render(request,'accounts/edit_profile.html',args)
else:
HttpResponse("hllo")
return redirect('/accounts/login')
#login_required
def change_password(request):
if request.user.is_authenticated():
if request.method == "POST":
form = PasswordChangeForm(data=request.POST,user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/accounts/profile')
else:
return HttpResponse("password does not match,go back and try again")
else:
form = PasswordChangeForm(user=request.user)
args = {'form' : form}
return render(request,'accounts/change_password.html',args)
else:
return redirect ('/accounts/login')
form.py
from django.contrib.auth.forms import UserCreationForm,UserChangeForm
from django.contrib.auth.models import User
#from django.forms import RegistrationForm,EditProfileForm
from django import forms
from accounts.models import Post
class HomeForm(forms.ModelForm):
post = forms.CharField(widget=forms.TextInput(
attrs={
'class':'form-control',
'placeholder' : 'write a post'
}
))
class Meta:
model = Post
fields = ('post',)
class Registrationform(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = (
'username',
'first_name',
'last_name',
'email',
'password1',
'password2',
)
def save(self,commit=True):
user=super(Registrationform,self).save(commit=False)
user.first_name= self.cleaned_data['first_name']
user.last_name=self.cleaned_data['last_name']
user.email=self.cleaned_data['email']
if commit:
user.save()
return user
class EditProfileForm(UserChangeForm):
#template_name = '/something/else'
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
'password'
)
and the error is
(.vEnv) jayu#broadwell-gt2:~/Desktop/tutorial$ heroku run python manage.py migrate
› Warning: heroku update available from 7.0.82 to 7.0.83
Running python manage.py migrate on ⬢ jaysuthar... up, run.5398 (Free)
/app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
Operations to perform:
Apply all migrations: accounts, contenttypes, auth, admin, sessions
Running migrations:
Rendering model states... DONE
Applying accounts.0002_auto_20180514_0523...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
utility.execute()
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 342, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 201, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 482, in alter_field
old_db_params, new_db_params, strict)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 564, in _alter_field
old_default = self.effective_default(old_field)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 210, in effective_default
default = field.get_db_prep_save(default, self.connection)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 728, in get_db_prep_save
prepared=False)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 720, in get_db_prep_value
value = self.get_prep_value(value)
File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1853, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: ''
Django keeps throwing the following when I deploying project (error is in migrate time when i run heroku run python manage.py migrate)
ValueError: invalid literal for int() with base 10: ''
i want to deploy this project on heroku, it successfully run till
git push heroku master --forc
but when i migrate database with this command :
heroku run python manage.py migrate
it gives error of valueerror.
where i did mistake ?
If you can provide any help I would greatly appreciate it.
EDIT :
accounts.0002_auto_20180514_0523 file :
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2018-05-14 05:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='userprofile',
name='phone',
field=models.IntegerField(default=0),
),
]
Obviously in it's first version your UserProfile's "phone" field was a CharField defaulting to the empty string. Changing an existing field's type requires a three-steps migrations: first create a new field with the desired type, create and apply the migration, then create a datamigration that will copy original data to the new field with proper transformations, error handling etc, and finally delete the original field (create and apply the migration).
BUT : in your case, making this field an integer is just plain wrong. A phone number is NOT an integer. First because you cannot add, substract, multiply or divide phone numbers, then because a phone number can contain non-numeric characters too (cf international phone numbers formats).
Thinking that everything made of numeric characters should be an int is a common beginner mistake (just like using floats instead of decimals for prices storage and calculations). When in doubt, ask yourself whether applying mathematical operations would make sense...
My code is as shown below:
models/user.py
from __future__ import unicode_literals
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import (
AbstractBaseUser, PermissionsMixin,BaseUserManager
)
class UserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email,and password.
"""
if not email:
raise ValueError('The given email must be set')
try:
with transaction.atomic():
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
except:
raise
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self._create_user(email, password=password, **extra_fields)
class User(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
"""
email = models.EmailField(max_length=40, unique=True)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
def save(self, *args, **kwargs):
super(User, self).save(*args, **kwargs)
return self
models/init.py
from user import User
settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
]
AUTH_USER_MODEL = 'dashboard.User'
After this when I run python manage.py migrate, it gives me the following error:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 164, in handle
pre_migrate_apps = pre_migrate_state.apps
File "/usr/local/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 218, in apps
return StateApps(self.real_apps, self.models)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 295, in __init__
raise ValueError("\n".join(error.msg for error in errors))
ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'dashboard.user', but app 'dashboard' doesn't provide model 'user'.
The field authtoken.Token.user was declared with a lazy reference to 'dashboard.user', but app 'dashboard' doesn't provide model 'user'.
Is it because of improper jwt token configuration or user model?
Have you tried retrieving your User model with get_user_model?
from django.contrib.auth import get_user_model
User = get_user_model()
I am trying to add a feature to where a new user needs to update his/her password on an initial login. I added a hidden BooleanField to my Profile model where default = True.
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
force_password_change = models.BooleanField(default=True)
However, when trying to use force_password_change in my views.py, it never returns the correct value that I set in django's admin page.
views.py
if request.method == 'POST':
...
user = authenticate(request, username=username, password=password)
changepass = UserProfile.objects.get(user=request.user)
if user:
if changepass.force_password_change == True:
changepass.force_password_change = False
changepass.save()
return HttpResponseRedirect('/login/register/')
elif changepass.force_password_change == False:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/main/')
else:
return HttpResponse("Your account has been disabled.")
It is currently giving me this error
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\exception.py", line
41, in inner
response = get_response(request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 187,
in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 185,
in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "start\views.py", line 20, in user_login
changepass = UserProfile.objects.get(user=request.user)
File "C:\Python34\lib\site-packages\django\db\models\manager.py", line 85,
in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Python34\lib\site-packages\django\db\models\query.py", line 380, in
get
self.model._meta.object_name
start.models.DoesNotExist: UserProfile matching query does not exist.
I also added AUTH_PROFILE_MODULE = 'start.UserProfile' to my settings.py, so that does not seem to be the problem.
You are forgetting to create UserProfile with the respected user
from django.db.models.signals import post_save
from models import UserProfile
from django.contrib.auth.models import User
def register(request):
if request.method == 'POST':
uf = UserForm(request.POST, prefix='user')
upf = UserProfileForm(request.POST, prefix='userprofile')
if uf.is_valid() and upf.is_valid():
user = uf.save()
userprofile = upf.save(commit=False)
userprofile.user = user
userprofile.save() # Are you missing this line ??
return django.http.HttpResponseRedirect(…something…)
This has nothing to do with boolean fields. The error is telling you that your specific User does not have a related entry in the UserProfile table.