Custom User model in Python with socialaccount - python

I would like to create a User model that has an additional couple fields in django. I tried to do so by following the advice
https://stackoverflow.com/a/22696794/3426600 to create a custom user model
in models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
user_data = models.TextField(null=True)
In settings.py
AUTH_USER_MODEL = 'app_name.User'
but when I run python manage.py syncdb
I get the errors:
CommandError: One or more models did not validate:
account.emailaddress: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
admin.logentry: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
auth.user: Model has been swapped out for 'app_name.User' which has not been installed or is abstract.
socialaccount.socialaccount: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
Could I be using the wrong app_name? If so, where do I find the app_name?
How do I make the custom user work with socialaccount, etc?

Assume your project strucutre is something like below, and the codes of User(AbstractUser) are located in mysite/mysite/app1/models.py:
mysite/ (root folder for the project, put it anywhere in your disk. Most developers have a workspace folder(s) in computer)
(other non-application things. E.g. a static/, README.md, ...)
manage.py
mysite/ (container for all applications. You can put applications directly under root folder, but not recommended)
__init__.py
settings.py
urls.py
wsgi.py
app1/ (each application resides in its own folder. You don't want to put all models in one models.py file or all views in one view.py file, right?)
__init__.py
models.py
views.py
......
Then the app_name is app1, i.e. AUTH_USER_MODEL = 'app1.User'. Meanwhile, you need to add mysite.app1 into INSTALLED_APPS in settings.py. This probably will solve you CommandError issue.
ADDED NOTES:
Each application, you can consider it as a module of your project. The app_name of the application is the folder name. If you have defined models in one application, must add it into INSTALLED_APPS in settings.py.
Manually creating a folder is not a good way. django-admin.py startapp is more recommended, because it together creates some common files for an application, e.g. init.py, models.py, view.py, ...
Suggest you to go through the django quick-start guide, if you haven't done it: https://docs.djangoproject.com/en/dev/intro/tutorial01/

Related

Django - Import Models from an installed Package

I have all of my Django models in another package which I install using pip in a Django app.
models_package
| - models.py
| - setup.py
and in models.py i have
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
....
in my Django app i have
my_django_app
| ...
| models.py
website
| ...
| settings.py
manage.py
in my_django_app.model i have
from models_package.models import *
and in the website i have added my_django_app as an app (add it to INSTALLED_APP) and in website.settings.py i have
AUTH_USER_MODEL = "my_django_app.User"
but when i run python manage.py runserver i get:
RuntimeError: Model class my_django_app.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
The Thing is User which comes from models_packages.models and models_packages is not a Django app which I add to INSTALLED_APP in settings.py. it is only a package containing all shared Models that I need in multiple different Django apps.
Is there any way to use models in models_package.models without adding it to INSTALLED_APP inside website.settings.py
i think you need to transform your 'my_django_app' to a django app:
all you need to do is to add app.py inside my_django_app package
from django.apps import AppConfig
class ApiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'my_django_app'
then you can add it to your INSTALLED_APP

Model not detected by Django, even with `app_label` referencing to an existing app

I have a Django project with an application called application.
The app is installed in the INSTALLED_APPS as follows:
### application/settings.py
INSTALLED_APPS = [
...
'application.apps.MyAppConfig',
]
with the AppConfig:
### application/apps.py
class MyAppConfig(AppConfig):
name = 'application'
verbose_name = 'My App'
label = 'application'
path = f"{os.environ.get('APP_DIR')}/application"
default = True
I have the models defined like this:
### data/models/basemodel.py
from django.db import models
class MyBaseModel(models.Model):
# ... fields ...
Meta:
app_label: `application`
Project's tree:
main_dir/
data/
__init__.py
models/
__init__.py
basemodel.py
application/
__init__.py
apps.py
urls.py
settings.py
...
Django is not finding the models, and if I run makemigrations Django responds No changes detected, and on migrate, the app application does not appear on the Operations to perform.
I want to split the data layer from the logic and interface layers. In order to do so, I've the models and other data-related business inside data (outside any installed app)
The goal is to link the models to the app from there, without having to declare any model inside the application dir.
The Model should be detected so the Django detects migrations to apply.
Context:
Django Application reference: doc
Django Models reference: doc
I guess you want to have a single module per model ? If so, you need to import your models inside models\__init__ like so:
from .basemodel import BaseModel
I also suggest that you define __all__ inside your init file, in order to import your models easily in other parts of the app:
__all__ = ["BaseModel"]
from .basemodel import BaseModel

Django app dissapears from Django Admin site when I add apps.py file

I'm working with Django 3.2 and trying to configure correctly the AppsConfig subclass of apps.py in order to avoid duplicate apps names when initzialing the project.
The context is the following. I have in my INSTALLED_APPS two apps whose names are equal although their paths not:
INSTALLED_APPS = [
...
'first_app.myapp',
'second_app.myapp'
]
To avoid the error shown below (and according to the documentation), I need to create an apps.py file subclassing AppConfig in at least one of the apps called myapp. I've decided to create that file in the second one, second_app.myapp.
django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: myapp
The app.py in second_app.myapp module looks like as follows:
from django.apps import AppConfig
class MySecondAppConfig(AppConfig):
name = "second_app.myapp"
label = "my_second_app"
And in the __init__.py I've added:
default_app_config = 'second_app.myapp.apps.MySecondAppConfig'
My admin.py looks like:
from django.contrib import admin
from .models import MyModel
class MySecondAppAdminModel(admin.ModelAdmin):
list_display = ('attr_1', 'attr_2')
admin.site.register(MyModel, MySecondAppAdminModel)
When I start the project all works OK and I can use that model information, views called from second_app.myapp also work OK.
The problem comes when I access to the admin site (http://localhost:8000/admin), where only appears the first_app.myapp admin form instead of both.
Can you help me? Thanks in advance.
instead of this:
INSTALLED_APPS = [
...
'first_app.myapp',
'second_app.myapp'
]
Just try this way only:
INSTALLED_APPS = [
...
'first_app',
'second_app'
]
You got that error because here first_app.myapp and second_app.myapp myapp is duplicate. you should not use like this in both the apps.
OR
INSTALLED_APPS = [
...
'first_app.apps.MyFirstAppConfig',
'second_app.apps.MySecondAppConfig'
]

Models and inheritance

Stumbled upon something very weird today.
I created a minimal project/application that can show the issue. This is how I did it:
virtualenv venv
. ./ven/bin/activate
pip install django==1.6 # That's the one we're using
django-admin.py startproject bla
cd bla
chmod +x manage.py
./manage.py startapp bla_app
in bla/settings.py:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bla_app',
)
AUTH_USER_MODEL = 'bla_app.MyUser'
in bla_app/models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class MyUser(AbstractUser):
super_name = models.CharField(max_length=254, unique=True)
Then, I run the syncdb command:
./manage.py syncdb
And it's been created as expected.
Now comes the tricky part. If I replace the models.py with a folder called models, and create an __init__.py file containing:
from my_user import MyUser
(the previous models.py was moved into models/ as my_user.py)
I then get these errors:
$ ./manage.py syncdb
CommandError: One or more models did not validate:
admin.logentry: 'user' has a relation with model bla_app.MyUser, which has either not been installed or is abstract.
auth.user: Model has been swapped out for 'bla_app.MyUser' which has not been installed or is abstract.
Do you have an idea of what is going on here?
I found that, but I'm not sure they're related
Django expects your model classes to be defined in models.py itself, not in a submodule. It's going to try to create an instance of models.MyUser which in your case does not exist in Django's world even though you've defined it in my_user.py
If you're looking to define each model in a separate Python file, you'd need to create a models.py file that imports them manually. This will likely be hard to maintain if you start creating a lot of models in that app.
app/
__init__.py
models.py
_models/
__init__.py
my_user.py
In models.py
from ._models.my_user import MyUser
To split your model into modules, you have to provide the app_label Meta Option. Ex:
my_user.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
super_name = models.CharField(max_length=254, unique=True)
class Meta:
app_label = 'bla_app'
As #petkostas said, it will not be required in Django 1.7 (issue 4470)
Take a look at this answer, which describes the process.

Struggling with Django syncdb

This drives me mad... I'm reorganizing an existing Django project using the following structure:
[project_abc]
[app]
[core]
[app1]
admin.py
models.py
...
[app2]
admin.py
models.py
...
... etc ... there's a total of 9 apps
[rest]
... rest api stuff, non-db related ...
[mobile]
... mobile stuff, non-db related ...
[
south
tastypie
[project_abc]
settings.py
urls.py
manage.py
All apps with models that require database access have been added to settings.py:
INSTALLED_APPS = (
'django.contrib.admin',
'[app].[core].[app1]',
'[app].[core].[app2]',
...
'tastypie',
'south'
)
Each model class has a Meta class like:
class Meta:
app_label=[app] # this points to the top level above [core]
Directories [app], [core] and subsequent [app] directories have an __init__.py file in them.
When I run syncdb, it happily ignores my apps under [core] however the tables for other apps like tastypie and south get created properly.
When I run manage.py validate it returns 0 errors found
I've read probably all posts and hints on topics related to syncdb but unfortunately to no avail. I'm obviously missing something, but cannot figure out what it is....
I can't fully understand which [app] is set in models Meta, but note that django syncdb uses django.db.models.get_apps to find projects' applications. Latter interspects apps from INSTALLED_APPS, and explicetely tries to load apps' models module with
models = import_module('.models', app_name)
So applications outside INSTALLED_APPS won't have tables synced.
Second, django loads all the models with django.db.models.get_apps for each found application, and latter turn introspects AppCache.apps_models (that cache is, as far as I remember, populated with register_models by model constructor). So all the imported models corresponding to valid applications are processed.
I guess you have to ensure that [app] from models._Meta:
contains models.py (possibly empty) which will make it a django application;
is mentioned in INSTALLED_APPS, to be asseccible with get_apps function.

Categories

Resources