Django user creation fails in the admin when filling profile fields - django

I'm using Django 1.4.1 with postgresql 9.1.
I need to add a profile to the User given with the auth app, and to allow the admin app to create and edit this profile.
Thus I've been following the docs section Storing additional information about users :
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.TextField(null = True, blank = True)
contact = models.TextField(null = True, blank = True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
settings.py
...
AUTH_PROFILE_MODULE = 'userprofile.UserProfile'
...
I also activated the django.contrib.auth and django.contrib.admin apps in INSTALLED_APPS.
admin.py
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'profile'
class UserAdmin(UserAdmin):
inlines = (UserProfileInline, )
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Problem
Now, when I run the admin app and ask to add (create) a new user, I'm asked to create my user through a two-step process : first, a page asking for only the username, password (twice), and my two UserProfile fields.
If I type only the username and the password (twice) and click "Save", I'm showed the second page of the process, which allows to fill in all the other User fields, as well as my UserProfile fields. There's a message saying "The user "xxxxx" was added successfully. You may edit it again below.", and fortunately I can edit fields from both models, it works.
But if I try to type anything into one or both of my UserProfile fields in the first page, the submit fails with the message :
IntegrityError at /admin/auth/user/add/
duplicate key value violates unique constraint "userprofile_userprofile_user_id_key"
DETAIL: Key (user_id)=(7) already exists.
The "7" is incremented each time I try.
How can that behavior be avoided, or alternatively how can I prevent the profile fields to be editable in the first page, but letting them be edited in the second page ?
Full traceback :
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/auth/user/add/
Django Version: 1.4.1
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'userprofile')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
366. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
196. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
69. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
25. return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
21. return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in inner
209. return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/admin.py" in add_view
114. extra_context)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
25. return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
21. return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in inner
209. return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in add_view
956. self.save_related(request, form, formsets, False)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in save_related
733. self.save_formset(request, form, formset, change=change)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in save_formset
721. formset.save()
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save
497. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save_new_objects
628. self.new_objects.append(self.save_new(form, commit=commit))
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in save_new
731. obj.save()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save
463. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save_base
551. result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py" in _insert
203. return insert_query(self.model, objs, fields, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in insert_query
1576. return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql
910. cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py" in execute
40. return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
52. return self.cursor.execute(query, args)
Exception Type: IntegrityError at /admin/auth/user/add/
Exception Value: duplicate key value violates unique constraint "userprofile_userprofile_user_id_key"
DETAIL: Key (user_id)=(7) already exists.`

As CadentOrange mentioned in a comment, the solution to this problem is described in this answer.
The problem is with using an inline admin form. Here's what happens:
It saves the main model (User)
Due to (1), The post_save signal handler for User is fired, which creates a new UserProfile object
Each inline model is saved (including another copy of your UserProfile, resulting in the dupe).

instead of
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
do a
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.get_or_create(user=instance)
You are creating new user profile object even for edit.

The create_user_profile signal and the admin form try to create the same UserProfile. You can override LocalUserAdmin to exclude the UserProfileInline from the add view :
class LocalUserAdmin(UserAdmin):
inlines = (UserProfileInline, )
def get_formsets_with_inlines(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
# hide MyInline in the add view
if isinstance(inline, UserProfileInline) and obj is None:
continue
yield inline.get_formset(request, obj), inline
see https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_formsets_with_inlines

Related

Django - IntegrityError at /add_location/ findlocation_app_location.user_id may not be NULL

models.py:
from django.contrib.auth.models import User
class Location(models.Model):
user = models.ForeignKey(User)
...
...
views.py:
class AddLocationPageView(CreateView):
model = Location
form_class = LocationForm
template_name = 'add_location.html'
success_url = '/add_location/location_added/'
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(AddLocationPageView, self).dispatch(*args, **kwargs)
forms.py:
from multiupload.fields import MultiFileField
from .models import Location, LocationType, Equipment, VisitTime, Photo
class LocationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(LocationForm, self).__init__(*args, **kwargs)
self.fields["types"].queryset = LocationType.objects.all()
self.fields["equipment"].queryset = Equipment.objects.all()
self.fields["visit_times"].queryset = VisitTime.objects.all()
class Meta:
model = Location
fields = ['name', 'types', 'equipment', 'visit_times', 'keywords', 'description']
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Напр. Стоунхендж'}),
'keywords': forms.TextInput(attrs={'placeholder': 'Напр. море, побережье, скалы'}),
'description': forms.Textarea(attrs={'placeholder': 'Любая информация, которую посчитаете нужной'}),
'types': forms.CheckboxSelectMultiple(),
'equipment': forms.CheckboxSelectMultiple(),
'visit_times': forms.CheckboxSelectMultiple(),
}
photos = MultiFileField(min_num=1, max_num=10)
def save(self, commit=True):
instance = super(LocationForm, self).save(commit)
for each in self.cleaned_data['photos']:
Photo.objects.create(photo=each, location=instance)
return instance
urls.py:
url(r'^add_location/$', AddLocationPageView.as_view(), name='add_location'),
When I am trying to save the location form I see the error.
What I have to do in order to get rid of this trouble?
Any advices will be a lot appreciated!
Thanks a lot!
I am adding traceback below for more clearness.
Traceback:
File "C:\commercial_projects\fl\lib\site-packages\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\utils\decorators.py" in _wrapper
34. return bound_func(*args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\utils\decorators.py" in bound_func
30. return func.__get__(self, type(self))(*args2, **kwargs2)
File "C:\commercial_projects\fl\src\findlocation_app\views.py" in dispatch
43. return super(AddLocationPageView, self).dispatch(*args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\views\generic\base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\views\generic\edit.py" in post
249. return super(BaseCreateView, self).post(request, *args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\views\generic\edit.py" in post
215. return self.form_valid(form)
File "C:\commercial_projects\fl\lib\site-packages\django\views\generic\edit.py" in form_valid
193. self.object = form.save()
File "C:\commercial_projects\fl\src\findlocation_app\forms.py" in save
33. instance = super(LocationForm, self).save(commit)
File "C:\commercial_projects\fl\lib\site-packages\django\forms\models.py" in save
459. construct=False)
File "C:\commercial_projects\fl\lib\site-packages\django\forms\models.py" in save_instance
105. instance.save()
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\base.py" in save
734. force_update=force_update, update_fields=update_fields)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\base.py" in save_base
762. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\base.py" in _save_table
846. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\base.py" in _do_insert
885. using=using, raw=raw)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\query.py" in _insert
920. return query.get_compiler(using=using).execute_sql(return_id)
File "C:\commercial_projects\fl\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
974. cursor.execute(sql, params)
File "C:\commercial_projects\fl\lib\site-packages\django\db\backends\utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\commercial_projects\fl\lib\site-packages\django\db\backends\utils.py" in execute
64. return self.cursor.execute(sql, params)
File "C:\commercial_projects\fl\lib\site-packages\django\db\utils.py" in __exit__
98. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\commercial_projects\fl\lib\site-packages\django\db\backends\utils.py" in execute
64. return self.cursor.execute(sql, params)
File "C:\commercial_projects\fl\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
318. return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /add_location/
Exception Value: findlocation_app_location.user_id may not be NULL
You have to understand what the problem is first. You have a foreign key to user field in model, but you exclude that in your form. Since user field cannot be empty, your save will be rejected by database. To set the foreign key for a ModelForm, you should override the form_valid method:
class AddLocationPageView(CreateView):
model = Location
def form_valid(self, form):
location = form.save(commit=False)
location.user = self.request.user
return super(CreateArticle, self).form_valid(form)
You could also include user in your form, so your form would contain the information when you save so there's no code change. But I bet that's not what you want because then your form would show a dropdown and let you select a user which doesn't make sense.
See django doc for what's going on with commit=False.

Django Model validate_unique method don't raise ValidationError

My model is :
class Inventory(models.Model):
canteen_id = models.IntegerField()
item = models.OneToOneField('Info',db_column='item_id')
I want item should be unique for each canteen_id. I used unique_togetherbut its not working as item is in OneToOneField.
I am using validate_unique method for my model and my code is now:
class Inventory(models.Model):
canteen_id = models.IntegerField()
item = models.OneToOneField('Info',db_column='item_id')
unit_price = models.CharField(max_length=50)
quantity = models.PositiveIntegerField(default=1)
sales_vat = models.DecimalField(decimal_places=2,max_digits=5,default=0.0)
date_time = models.DateField(auto_now=False,auto_now_add=True)
def vat_count(self):
self.item_price = Decimal(self.unit_price)
self.vat = (self.item_price * 15)/100
return self.vat
def validate_unique(self, exclude=None):
qs = Inventory.objects.filter(canteen_id=self.canteen_id)
if self.pk is None:
if qs.filter(item=self.item).exists():
raise ValidationError("item already exists")
def save(self, *args,**kwargs):
self.canteen_id = CANTEEN_ID
self.sales_vat = self.vat_count()
self.unit_price = Decimal(self.unit_price)
self.validate_unique()
super(Inventory,self).save(*args, **kwargs)
Now when I am trying to add same item and canteen_id, it don't raise any error message in form page. It shows error. Error:
Environment:
Request Method: POST
Request URL: http://localhost:8000/admin/item/inventory/add/
Django Version: 1.9.2
Python Version: 2.7.6
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'item',
'bill',
'system']
Installed 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.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
541. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
244. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in add_view
1437. return self.changeform_view(request, None, form_url, extra_context)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
67. return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
63. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in inner
184. return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in changeform_view
1378. self.save_model(request, new_object, form, not add)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in save_model
991. obj.save()
File "/home/harun/Desktop/nutboltu/canteenLatest/CanteenKiosk/diucanteen/item/models.py" in save
34. self.validate_unique()
File "/home/harun/Desktop/nutboltu/canteenLatest/CanteenKiosk/diucanteen/item/models.py" in validate_unique
27. raise ValidationError("item already exists")
Exception Type: ValidationError at /admin/item/inventory/add/
Exception Value: [u'item already exists']
What is the solution???
If you override validate_unique method in your model you should call super as you do in save/delete etc.
def validate_unique(self, exclude=None):
# custom logic
super(Inventory, self).validate_unique(exclude=exclude)
Thanks all to help me find out my problem. My code was correct but I made a mistake in query. I am getting canteen_id value by assigning a variable CANTEEN_ID in settings.py and save it by save() method.
So, My query should be:
from projectdir.settings import CANTEEN_ID
def validate_unique(self,exclude=None):
qs = Inventory.objects.filter(canteen_id=CANTEEN_ID)
Firstly, I think unique_together should work with a one to one field. If you can create a simple test case that shows that it doesn't, then it would be worth creating a bug report.
If you do want to check the unique constraint manually, don't do it in the save() method. The Django admin doesn't expect a validation error to be raised in the save method, so you get the error. Instead, override the model's clean method, and do the check in. Model forms, including the ones in the Django admin, will call the clean method when processing the form data.
class Inventory(models.Model):
...
def clean(self):
qs = Inventory.objects.filter(canteen_id=self.canteen_id)
if self.pk is None:
if qs.filter(item=self.item).exists():
raise ValidationError("item already exists")
See the docs on validating objects for more info.
The way CANTEEN_ID is provided for save method may hide solution.

Django Admin Issue - 'NoneType' object has no attribute 'user'

Writing a blog engine with Django 1.5 and using the Django Admin. Everything was fine, until I added a ManyToManyField to a model, and added that field to the ModelAdmin's fieldsets, then I started to get this mysterious error when trying to load the admin page:
'NoneType' object has no attribute 'user'
(Full stack trace further on below.) Why would the response object suddenly be None? If I remove the field from the fieldset, everything's fine again.
My models look something a bit like this (lots of fields removed):
class Tag(models.Model):
name = models.CharField(max_length=30)
class Post(models.Model):
title = models.CharField(max_length=300)
tags = models.ManyToManyField(Tag)
author = models.CharField(max_length=100)
And the ModelAdmin looks a bit like this:
class PostAdmin(admin.ModelAdmin):
# Order
fieldsets = (
('Content', {
'fields': ('title', 'tags')
}),
)
def formfield_for_dbfield(self, db_field, request, **kwargs):
# Pre-fill 'author' with logged in name
if db_field.name == "author":
kwargs['initial'] = "%s %s" % (request.user.first_name, request.user.last_name)
return db_field.formfield(**kwargs)
return super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
And it's when I remove 'tag's from the fieldsets that all is well again. It could be that I'm making some simple Django Admin mistake, I haven't used it much before, but the best I could find googling was some bug that was fixed three years ago, and I'm sure I'm running 1.5.1.
Here's the full stack trace:
Internal Server Error: /theadmin/blog/post/1/
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py", line 372, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py", line 89, in _wrapped_view_
unc
response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py", line 202, in inner
return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py", line 25, in _wrapper
return bound_func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py", line 21, in bound_func
return func(self, *args2, **kwargs2)
File "C:\Python27\lib\site-packages\django\db\transaction.py", line 223, in inner
return func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py", line 1081, in change_view
ModelForm = self.get_form(request, obj)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py", line 465, in get_form
return modelform_factory(self.model, **defaults)
File "C:\Python27\lib\site-packages\django\forms\models.py", line 424, in modelform_factory
return type(form)(class_name, (form,), form_class_attrs)
File "C:\Python27\lib\site-packages\django\forms\models.py", line 212, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "C:\Python27\lib\site-packages\django\forms\models.py", line 170, in fields_for_model
formfield = formfield_callback(f, **kwargs)
File "E:\Dropbox\PassionateAbout\PassionateAboutJustice\blog\admin.py", line 35, in formfield_for
dbfield
return super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py", line 125, in formfield_for_
bfield
related_modeladmin.has_add_permission(request))
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py", line 284, in has_add_permis
ion
return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission())
AttributeError: 'NoneType' object has no attribute 'user'
Your swallowing the request. Here you take it:
def formfield_for_dbfield(self, db_field, request, **kwargs):
but then you don't pass it on:
return super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
However the original - https://github.com/django/django/blob/stable/1.5.x/django/contrib/admin/options.py#L88
is defined as:
def formfield_for_dbfield(self, db_field, **kwargs):
So you should keep the same signature when you override.
Please note: the original will do:
request = kwargs.pop("request", None)
If you want to access the request, don't do the same, because "pop()" will remove it from kwargs. Just access without deleting:
request = kwargs['request']
so your super call still passes the request through.
It only came to light with the M2M field because that needs the request to look up permissions of the current user (for the related model) whereas CharField doesn't really need the request, so doesn't mind that it's None. (which the above pop() call will do if request is not found)
End result:
def formfield_for_dbfield(self, db_field, **kwargs):
# Pre-fill 'author' with logged in name
if db_field.name == "author":
request = kwargs['request']
kwargs['initial'] = "%s %s" % (request.user.first_name, request.user.last_name)
return db_field.formfield(**kwargs)
return super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)

IntegrityError _id may not be NULL

Just starting with Django and have began creating an application for test purposes. However, when I specify rollercoasters to ManyToMany and add an instance of a Park via the admin UI I get an:
IntreityError, rollercoasters_id may not be NULL
I have just completed a book on this and the code is more or less exact as the books (the code works in the book).
What am I doing wrong?
The application works when I have ForeignKey instead of ManyToMany
from django.db import models
class Company(models.Model):
name=models.CharField(max_length=30)
location=models.CharField(max_length=30)
website=models.URLField()
def __unicode__(self):
return self.name
class Constructor(models.Model):
name=models.CharField(max_length=30)
location=models.CharField(max_length=30)
contactnumber=models.CharField(max_length=30)
website=models.URLField()
def __unicode__(self):
return self.name
class RollerCoasters(models.Model):
name=models.CharField(max_length=30)
dateopenned=models.DateField
type=models.CharField(max_length=30)
builtby=models.ForeignKey(Constructor)
dateopenned=models.DateField()
def __unicode__(self):
return self.name
class Parks (models.Model):
name=models.CharField(max_length=30)
parent=models.ForeignKey(Company)
location=models.CharField(max_length=1000)
rollercoasters=models.ManyToManyField(RollerCoasters)
dateopenned=models.DateField()
def __unicode__(self):
return self.name
Error:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/Parks/parks/add/
Django Version: 1.4.2
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'Parks',
'django.contrib.admin',
'django.contrib.admindocs')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in wrapper
366. return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
196. return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapper
25. return bound_func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in bound_func
21. return func(self, *args2, **kwargs2)
File "C:\Python27\lib\site-packages\django\db\transaction.py" in inner
209. return func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in add_view
955. self.save_model(request, new_object, form, False)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in save_model
709. obj.save()
File "C:\Python27\lib\site-packages\django\db\models\base.py" in save
463. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "C:\Python27\lib\site-packages\django\db\models\base.py" in save_base
551. result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "C:\Python27\lib\site-packages\django\db\models\manager.py" in _insert
203. return insert_query(self.model, objs, fields, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py" in insert_query
1593. return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
910. cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\util.py" in execute
40. return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
344. return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /admin/Parks/parks/add/
Exception Value: Parks_parks.rollercoasters_id may not be NULL
You can't just swap between a foreign key and many to many field. If you have a foreign key, Django creates a database column e.g. rollercoaster_id. If you use a many to many, Django creates an intermediary join table.
To switch from a foreign key to a many to many field, you must do one of the following:
drop the tables and then run syncdb so that Django recreates them. You will lose any data.
manually update the database schema yourself, using the output of the manage.py sql command as a guide
use the schema migration tool South.

How do I fix IntegrityError with UserProfile model (when User created from admin interface)?

EDIT1: I tried doing sqlflush to reset everything, but that didn't help.
EDIT2: I am able to create a user and specify OtherModel as NULL, and then edit the user later to make othermodel an actual reference. The problem occurs when I specify a reference during user creation.
So in my app, which is hooked up with postgres, I'm trying to extend the User model that django provides with a new model called UserProfile. I want each User to be associated with another model I created. So here's my code:
models.py
.
.
.
class OtherModel(models.Model):
# model info
class UserProfile(models.Model):
user = models.OneToOneField(User)
othermodel = models.OneToOneField(OtherModel, null=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
When I create a User from the django admin interface, I get the following error:
IntegrityError at /admin/auth/user/add/
duplicate key value violates unique constraint "planamocal_userprofile_user_id_key"
DETAIL: Key (user_id)=(23) already exists.
Everytime I try to make a new user, the user_id count keeps incrementing, which is weird because my actual user count stays the same.
Here's the backtrace:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/auth/user/add/
Django Version: 1.3.1
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'planamocal',
'django.contrib.admin']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
307. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
93. response = view_func(request, *args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
79. response = view_func(request, *args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
197. return view(request, *args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
28. return bound_func(*args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
93. response = view_func(request, *args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
24. return func(self, *args2, **kwargs2)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/transaction.py" in inner
217. res = func(*args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/contrib/auth/admin.py" in add_view
103. return super(UserAdmin, self).add_view(request, form_url, extra_context)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
28. return bound_func(*args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
93. response = view_func(request, *args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
24. return func(self, *args2, **kwargs2)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/transaction.py" in inner
217. res = func(*args, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
885. self.save_formset(request, form, formset, change=False)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_formset
677. formset.save()
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/forms/models.py" in save
482. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/forms/models.py" in save_new_objects
613. self.new_objects.append(self.save_new(form, commit=commit))
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/forms/models.py" in save_new
717. obj.save()
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/base.py" in save
460. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/base.py" in save_base
553. result = manager._insert(values, return_id=update_pk, using=using)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/manager.py" in _insert
195. return insert_query(self.model, values, **kwargs)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/query.py" in insert_query
1436. return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
791. cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
735. cursor.execute(sql, params)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/backends/util.py" in execute
34. return self.cursor.execute(sql, params)
File "/Users/AndyFang/Desktop/planamo/venv/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
44. return self.cursor.execute(query, args)
Exception Type: IntegrityError at /admin/auth/user/add/
Exception Value: duplicate key value violates unique constraint "planamocal_userprofile_user_id_key"
DETAIL: Key (user_id)=(23) already exists.
How to fix this error?
The problem occurs because it appears you are trying to create a user profile and add the other model simultaneously in the admin.
Since the other model is a signal connected to the user creation, therefore, it is impossible.
Change the work flow such that you create the user, save user, create profile, save profile and add other model, save profile (in this order)