Django IntegrityError on user signup - python

I am getting an error when I try to extend user profile using django-allauth
Exception Type: IntegrityError at /accounts/signup/
Exception Value: workerapp_userprofile.user_id may not be NULL
This is my models.py in my workerapp app of my django project where I am asking for two additional fields along with other signup information.
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User, unique=True)
# The additional attributes we wish to include.
website = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_images', blank=True)
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
My user is saving correctly which I can see in the admin, it's just the showing this error during the signup.

Related

Field defines a relation with the model 'auth.User', which has been swapped out.(fields.E301)

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

How to prevent deletion of instance from Inline in Django Admin correctly?

I have two models look like:
class Client(models.Model):
# some client fields
class User(models.Model):
# some user fields
owned_by = models.ForeignKey(Client, on_delete=models.CASCADE)
is_main_user = models.BooleanField()
Also I made admin part. StackedInline for User and ModelAdmin for Client which includes UserStackedInline.
My goal is prevent deleting User which has is_main_user==True. I've made signal handler for pre_delete from User and raise ValidationError("You cannot delete main user") when condition is true. But when I try to delete user in admin, I was getting 500 error. I've expected to get readable message in admin.
How I can correctly handle ValidationError on instance deletion in StackedInline?
Or am I incorrectly preventing a specific instance from being deleted?
You could use formsets.
admin.py:
from django.contrib import admin
from django.core.exceptions import ValidationError
from django.forms import BaseInlineFormSet
from .models import *
class PageFormSet(BaseInlineFormSet):
def clean(self):
super(PageFormSet, self).clean()
for form in self.forms:
if not hasattr(form, 'cleaned_data'):
continue
data = form.cleaned_data
if (data.get('DELETE') and form.instance.is_main_user):
raise ValidationError('You cannot delete main user')
class UserInline(admin.StackedInline):
model = User
formset = PageFormSet
class ClientAdmin(admin.ModelAdmin):
inlines = [UserInline]
admin.site.register(Client, ClientAdmin)

Django User model foreign key failed

I am using django 2.0. For users I am using the model django.contrib.auth.models.User. I have stored a user with username john in it. I have a Post model which uses a User model as ForeignKey. This is my models.py:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
post_content = models.CharField(max_length=140)
post_date = models.DateTimeField('post date')
post_user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.post_content
...In my views.py I am creating a post with:
from django.contrib.models import User
Post.objects.create(post_content=post_text, post_date=timezone.now(),post_user=User.objects.get(username='john'))
...In one part of the code. When I run I get this error:
FOREIGN KEY constraint failed
IntegrityError at /
And it points to the line in which I create the user in views.py.
Is there a proper way to ForeignKey a user model? Any guidance appreciated. Thank you :-).
EDIT:It works after doing a reset to the database because I made an error with migrations. Run you migrations properly friends!

Correct way to add fields to a model on django

I have a User model and i want to add a new field to the user, in the database and in the user form. i have looked online many differente ways to do this but i want to know what is the "correct" way to do it. Specially the correct way to create migrations.
Django Version: (1,10,0,u'final',1)
Not sure if I got what you're looking for but let's say you want to add a "Status" field to your User model, and then have it in the Admin panel so you can interact with it (update, change, etc...).
in models.py - we are creating a Profile class which will be linked to a User and then a status to be added to a user:
class Profile(models.Model):
" A profile added User """
user = models.OneToOneField(User, on_delete=models.CASCADE)
# so to link the profile to a user
status = models.CharField(max_length=100, blank=True)
# a field status
def __str__(self):
return self.status
in admin.py - we are integrating the newly created Profile to the user
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
verbose_name_plural = 'Profile'
fk_name = 'user'
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline, )
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
# And then we unregister the User class and register the two updated ones
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
Don't forget to run /manage.py makemigrations and then /manage.py migrate to update the database.
Let me know if that answer your question.

Unable to autopopulate a Django admin field using an attribute from a OneToOne relationship

There are similar questions to this, but I believe mine is different. I am very new to Django and to Python, so please forgive my ignorance.
I have a custom class UserProfile that inherits from the django.contrib.auth.models User class. This UserProfile is based on the exercise in Tango with Django, however, I am using the example to create a different project/app.
I have UserProfile linked to the standard User model with a OneToOneField relationship in my models.py, as shown below:
class UserProfile(models.Model):
# Links UserProfile to a User model instance.
user = models.OneToOneField(User)
# The additional attribute I wish to include that isn't in User.
slug = models.SlugField(unique=True)
In my admin.py file, I want an interface for UserProfile that I can work with, and I want the slugfield to autopopulate when I enter a new UserProfile. I want it to autopopulate based on the username attribute of User. However, I can't seem to make it work. Here is my admin.py code:
class UserProfileAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("user.username",)}
When I try to runserver from my command line, I get the following error:
ERRORS: <class 'climbcast.admin.UserProfileAdmin'>: (admin.E030) The
value of >'prepopula ted_fields["slug"][0]' refers to 'user.username',
which is not an attribute of >' climbcast.UserProfile'.
System check identified 1 issue (0 silenced).
It won't allow me to access the user.username attribute this way, even though I can access it that way in the python shell. Any ideas on how to make this work?
Unfortunately prepopulated_fields doesn’t accept DateTimeField, ForeignKey, nor ManyToManyField fields.
Source: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields
Possible solution, in your models.py (make slug attribute optional):
from django.utils.encoding import force_text
from django.template.defaultfilters import slugify
class UserProfile(models.Model):
[...]
slug = models.SlugField(blank=True, db_index=True, unique=True)
def get_unique_slug(self, value):
"""
Generate a valid slug for a for given string.
"""
qs = self.__class__.objects.all()
used = qs.values_list('slug', flat=True)
i = 1
baseslug = slugify(value)
while slug in used:
slug = '%s-%s' % (baseslug, i)
i += 1
return slug
def save(self, *args, **kwargs):
if not self.slug and self.user:
self.slug = self.get_unique_slug(force_text(self.user.username))
super(UserProfile, self).save(*args, **kwargs)

Categories