Django 1.6 AbstractUser m2m models validation error - python

I don't have errors with Django 1.5.4 (stable), but when I was testing my application on Django 1.6 beta 4 from official tar.gz I got error with validation models on startup.
models.py
from django.contrib.auth.models import AbstractUser, User
class ShopUser(AbstractUser):
model_car = models.CharField(max_length=200)
date_car = models.DateField()
description = models.TextField(blank=True, db_index=True)
manager = models.ForeignKey(User)
This is manage.py runserver console log:
Validating models...
Unhandled exception in thread started by <function wrapper at 0x2d941b8>
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 93, in wrapper
fn(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 97, in inner_run
self.validate(display_num_errors=True)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 312, 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:
adminka.shopuser: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'.
adminka.shopuser: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'.
auth.user: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'.
auth.user: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'.
python -c "import django;print django.get_version()"
1.6b4
What need to do for solve this problem?

You must declare AUTH_USER_MODEL on your settings.py. In your case:
AUTH_USER_MODEL = 'your_app.ShopUser'

For me this was fixed in Django 1.6.5 by changing this:
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
pass
to this:
from django.contrib.auth.models import AbstractBaseUser
class CustomUser(AbstractBaseUser):
pass
No other changes needed in Django 1.6.5. #Stormlifter's suggestion has merit but I am using this CustomUser with this stuff for OAuth2 via python-social-auth:
$ pip freeze
Django==1.6.5
Markdown==2.4.1
MySQL-python==1.2.5
PyJWT==0.2.1
South==1.0
basicauth==0.2
boto==2.28.0
django-filter==0.7
django-guardian==1.2.0
django-storages==1.1.8
djangorestframework==2.3.14
httplib2==0.9
oauth2==1.5.211
oauthlib==0.6.3
python-memcached==1.53
python-oauth2==0.7.0
python-openid==2.2.5
python-social-auth==0.2.1
requests==2.4.1
requests-oauthlib==0.4.1
shortuuid==0.4.2
six==1.7.2
wsgiref==0.1.2
My new CustomUser will be doing more than the default user and does need to be the AUTH_USER_MODEL='myapp.CustomUser' in settings.py as #jordiburgos suggested.
I hope this helps!

You want to inherit from AbstractBaseUser not from AbstractUser.
However, it looks like you just want to store some additional information for users, I wouldn't recommend using a custom user model for this. Just use relationships.
class ShopUser(models.Model):
model_car = models.CharField(max_length=200)
date_car = models.DateField()
description = models.TextField(blank=True, db_index=True)
user = models.OneToOneField(User)
You could make that a ForeignKey if you need Multiple ShopUser's to relate to a single user, but I think OneToOne makes the most sense.
As told by Django Documents:
Specifying a custom user model
AbstractBaseUser

Related

Django ModelTranslation local fields clash with parent´s model fields

I´m developing a website with Mezzanine and I´m having problem trying to configure modelTranslation plugin for it.I´m using Django 1.8.9 and Mezzanine 4.0.1, django_modeltranslation 0.11.
I have a model class GenericContent with some fields :
class GenericContent(models.Model):
image_footer = RichTextField(blank=True)
video_footer = RichTextField(blank=True)
summary = RichTextField(blank=True)
class BasicContent(Page, RichText, GenericContent):
pass
In the translation.py file for the basicContent app, we have the following modelTranslation translation definitions :
class TranslatedGenericContent(TranslationOptions):
fields = ('summary',
'image_footer',
'video_footer',)
class TranslatedBasicContent(TranslationOptions):
pass
translator.register(GenericContent, TranslatedGenericContent)
translator.register(BasicContent, TranslatedBasicContent)
With this configuration, it doesn´t show errors, but the basicContent doesn´t get translated(the inherited fields from genericContent are registered for translation, but in basicContent they don´t get translated, nor any other fields from the parent classes[Page and RichText], which are Mezzanine included classes and registered for translation).
If I try to modify the translation.py file :
class TranslatedGenericContent(TranslationOptions):
fields = ('summary',
'image_footer',
'video_footer',)
translator.register(GenericContent, TranslatedGenericContent)
translator.register(BasicContent, TranslatedGenericContent)
This other configuration gives and error when trying to run python manage.py sync_translation_fields
basicContent.BasicContent.image_footer_en: (models.E006) The field 'image_footer_en' clashes with the field 'image_footer_en' from model 'basicModels.genericcontent'.
basicContent.BasicContent.image_footer_es: (models.E006) The field 'image_footer_es' clashes with the field 'image_footer_es' from model 'basicModels.genericcontent'.
basicContent.BasicContent.summary_en: (models.E006) The field 'summary_en' clashes with the field 'summary_en' from model 'basicModels.genericcontent'.
basicContent.BasicContent.summary_es: (models.E006) The field 'summary_es' clashes with the field 'summary_es' from model 'basicModels.genericcontent'.
basicContent.BasicContent.video_footer_en: (models.E006) The field 'video_footer_en' clashes with the field 'video_footer_en' from model 'basicModels.genericcontent'.
basicContent.BasicContent.video_footer_es: (models.E006) The field 'video_footer_es' clashes with the field 'video_footer_es' from model 'basicModels.genericcontent'.
Have you ever experienced this problem? I´m looking into a fix for this. Any help would be appreciated!

How to add new columns to django userprofile model

I have added one extra custom field phone to Django user authentication. Till then it worked properly. Later I added one more custom field called permissions. After that I am facing an error message when I try to access the admin page. Here is my model.py code
from django.contrib.auth.models import User
from django.db import models
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)
class Meta:
permissions = (
("ssc_1","can access ssc locked questions"),
)
# The additional attributes we wish to include.
phone = models.CharField(max_length =20)
permission = models.IntegerField()
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
I have followed this stackoverflow answer, when I issue python manage.py migrate command, I am getting this error message
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: table "users_userprofile" already exists
Note : My Django versions is 1.6.6
Thanks
Migrations were introduced only in django 1.7. Until then south was being used to handle migrations

Extending Django Auth User model

admin.py
class NetUserInline(admin.StackedInline):
model = NetUser
class UserProfileAdmin(UserAdmin):
inlines = [NetUserInline, ]
admin.site.register(User, UserProfileAdmin)
models.py
class NetUser(AbstractUser):
Net_30 = models.BooleanField(default=False)
site.register(NetUser)
im getting error like this.
django.core.management.base.CommandError: One or more models did not validate:
accounts.netuser: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'.
accounts.netuser: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'.
auth.user: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'.
auth.user: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'.
The Django User model is automatically part of any Django project. That is to say that the User model will create all database tables that are part of it at the same time you run syncdb. You have subclassed AbstractUser for your NetUser class, meaning that all the fields that are part of AbstractUser are part of NetUser as well. So, right now your database has tables such as this...
User
username
password
email
...
NetUser
username
password
email
...
net_30
As part of Django's user administration, database tables are created that manage what groups/permissions users have within your application(s). Right now it appears that this system is attempting to connect to both the standard User model and your NetUser model. I'd assume this is because by subclassing AbstractUser Django attempts to create all relations to that user model. At the same time, if you haven't specified that you are using a custom user model then Django will be attempting to do the same to the standard user model.
The documentation states you must specify what you are using for a user model if not the default by adding AUTH_USER_MODEL = 'Accounts.NetUser' to your settings.py file. This tells your Django project that you are using a custom User model and not connect to the standard User model. Right now both are happening.
Furthermore, you should change admin.site.register(User, UserProfileAdmin) to admin.site.register(NetUser, UserProfileAdmin) so that your Admin backend is looking at your custom User model and not the standard Django User model.
You probably forgot to set AUTH_USER_MODEL in settings.py
AUTH_USER_MODEL = 'myapp.NetUser'
docs: substituting-a-custom-user-model
PS: However using some kind of profile imho is generally less painful )

django.core.exceptions.ImproperlyConfigured

I have recently moved to another machine and have had to check my project out from subversion again, but I am pretty sure this computer has Django 1.8 and the project is expecting 1.7.
I have tried to sync my db with the code to create the necessary tables but I get the following error.
C:\Users\jont\Documents\ATP\Webapp>manage.py syncdb
C:\Python27\lib\site-packages\admin_tools\utils.py:9: RemovedInDjango19Warning:
django.utils.importlib will be removed in Django 1.9.
from django.utils.importlib import import_module
c:\users\jont\documents\django-trunk\django\contrib\contenttypes\models.py:148:
RemovedInDjango19Warning: Model class django.contrib.contenttypes.models.ContentType doesn't de
her isn't in an application in INSTALLED_APPS or else was imported before its application was
loaded. This will no longer be supported in Django 1.9.
class ContentType(models.Model):
C:\Python27\lib\site-packages\admin_tools\dashboard\modules.py:8: RemovedInDjango19Warning: The
django.forms.util module has been renamed. Use django.forms.utils instead.
from django.forms.util import flatatt
C:\Python27\lib\site-packages\django_tables2\tables.py:171: RemovedInDjango19Warning: SortedDict
is deprecated and will be removed in Django 1.9. attrs["base_columns"] =
SortedDict(parent_columns)
C:\Python27\lib\site-packages\django_tables2\tables.py:193: RemovedInDjango19Warning: SortedDict
is deprecated and will be removed in Django 1.9.
attrs["base_columns"].update(SortedDict(cols))
Traceback (most recent call last):
File "C:\Users\jont\Documents\ATP\Webapp\manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "c:\users\jont\documents\django-trunk\django\core\management\__init__.py", line 336, in
execute_from_command_line
utility.execute()
File "c:\users\jont\documents\django-trunk\django\core\management\__init__.py", line 310, in
execute
django.setup()
File "c:\users\jont\documents\django-trunk\django\__init__.py", line 23, in setup
apps.populate(settings.INSTALLED_APPS)
File "c:\users\jont\documents\django-trunk\django\apps\registry.py", line 115, in populate
app_config.ready()
File "c:\users\jont\documents\django-trunk\django\contrib\admin\apps.py", line 22, in ready
self.module.autodiscover()
File "c:\users\jont\documents\django-trunk\django\contrib\admin\__init__.py", line 24, in
autodiscover
autodiscover_modules('admin', register_to=site)
File "c:\users\jont\documents\django-trunk\django\utils\module_loading.py", line 73, in
autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module
__import__(name)
File "C:\Users\jont\Documents\ATP\Webapp\jobs\admin.py", line 4, in <module>
from jobs.views import registration
File "C:\Users\jont\Documents\ATP\Webapp\jobs\views.py", line 12, in <module>
from jobs.forms import ApplicantForm, JobForm, \
File "C:\Users\jont\Documents\ATP\Webapp\jobs\forms.py", line 8, in <module>
class JobForm(forms.ModelForm):
File "c:\users\jont\documents\django-trunk\django\forms\models.py", line 272, in __new__
"needs updating." % name
django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form JobForm needs updating.
django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form JobForm needs updating.
Like the error mentions, you need to explicitly specify the fields, or exclude.
Try this
class JobForm(models.ModelForm):
#fields
class Meta:
model = Job
fields = "__all__"
which would include all the fields
Here is the relevant documentation (release notes 1.6)
Previously, if you wanted a ModelForm to use all fields on the model,
you could simply omit the Meta.fields attribute, and all fields would
be used.
This can lead to security problems where fields are added to the model
and, unintentionally, automatically become editable by end users. In
some cases, particular with boolean fields, it is possible for this
problem to be completely invisible. This is a form of Mass assignment
vulnerability.
For this reason, this behavior is deprecated, and using the
Meta.exclude option is strongly discouraged. Instead, all fields that
are intended for inclusion in the form should be listed explicitly in
the fields attribute.
If this security concern really does not apply in your case, there is
a shortcut to explicitly indicate that all fields should be used - use
the special value "__all__" for the fields attribute
You can set fields or exclude in the ModelForm in Django 1.7.
It changes in 1.8, you should set fields or exclude in the Meta class within ModelForm.
class JobForm(models.ModelForm):
#fields
class Meta:
model = Job
fields = "__all__"
I got the same error when I set "Meta" inner class without "fields" or "exclude" attributes in "NewUserForm(UserCreationForm)" class in "account/forms.py" to create a form as shown below:
# "account/forms.py"
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class NewUserForm(UserCreationForm):
class Meta: # Here
model = User
So, I added "fields" attribute to "Meta" inner class as shown below:
# "account/forms.py"
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class NewUserForm(UserCreationForm):
class Meta: # Here
model = User
fields = ("username",) # Here
Or, added "exclude" attribute to "Meta" inner class as shown below:
# "account/forms.py"
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class NewUserForm(UserCreationForm):
class Meta: # Here
model = User
exclude = ("first_name", "last_name") # Here
Then, I could solve the error.
Dropping to Django 1.7 seemed to do the trick. There didn't seem to be an easy way to adapt the code to fit Django 1.8.

Django ORM cannot resolve keyword for related field for aggregate when model used by more than one application

In Django 1.5 I have 3 apps: common, app1, app2 in which I have the following (simplified) models:
# common/models.py
class ApiUser(models.Model):
username = models.CharField(max_length=255)
channel = models.CharField(max_length=20)
# app1/models.py
class Place(models.Model):
title = models.CharField(max_length=255)
created_by = models.ForeignKey('common.ApiUser', null=True, related_name="%(app_label)s_places")
# app2/models.py
class Tag(models.Model):
name = models.CharField(max_length=255)
user = models.ForeignKey('common.ApiUser', null=True, related_name="%(app_label)s_tags")
app1 is listed before app2 in INSTALLED_APPS.
When I try to create the following queryset:
qs = ApiUser.objects.filter(channel='app1').annotate(Count('app1_places'))
I get back:
Cannot resolve keyword 'app1_places' into field. Choices are: app2_tags, channel, username
Where the list of choices provided does not include 'app1_places' but does contain 'app2_tags'. However if I try to reference app1_places on a model instance I don't get an error; it works fine:
>>> u = ApiUser.objects.get(pk=23)
>>> u.app1_places.all()
[]
Annotate with app2_tags works too:
qs = ApiUser.objects.filter(channel='app2').annotate(Count('app2_tags'))
Is this a bug in django or is there something I am doing wrong configuring these fields.
edit: here is the stack trace:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/query.py", line 795, in annotate
is_summary=False)
File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1019, in add_aggregate
field_list, opts, self.get_initial_alias(), False)
File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1337, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'app1_places' into field. Choices are: app2_tags, channel, username
Note: some app1 models are using the GeoDjango GeoManager (including places) but there are also models in app1 which don't use the geomanager and have foreign keys that also do not work with annotate.
It turns out the issue was with a proxy model that was on app1 and not app2. The proxy model had a custom manager:
# app1/models.py
class App1User(common_models.ApiUser):
objects = common_models.ApiUser.objects.filter(channel='app1')
class Meta:
proxy = True
App2 is not using a corresponding proxy model for ApiUser. When django first loads all the models to determine the model domain and calculate backwards references the overridden manager in the proxy model short-circuited the loading of app1.models, leaving all the backwards references for that module uninitialised.
Removing the custom manager definition resolved the issue.

Categories