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.
Related
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
I am following Django official tutorial and I got stuck at the second part. In particular, I can't have my newly created model displayed in the admin panel. Step by step:
I created a new app;
I add it to settings.py (see below);
I edited the models.py file (see below);
I ran my first migration, succesfully;
(I check on MySQL and everything was created ok);
I change the admin.py file (see below);
I refreshed maniacally the admin panel with no results.
myproject/myproject/settings.py:
[...]
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
)
[...]
myproject/myapp/models.py:
from django.db import models
class Question(models.Model):
body = models.CharField(max_length=200)
myproject/myapp/admin.py:
from django.contrib import admin
from .models import Question
admin.site.register(Question)
What I am doing wrong?
How do you start the debug-server? Did it restarts after your changing the code? Try to stop the debug server and start over again with --nothreading option.
This works for me
from django.contrib import admin
from .models import Role
class RoleAdmin(admin.ModelAdmin):
class Meta:
model = Role
admin.site.register(Role,RoleAdmin)
Does it make sense for you?
Try killing or restarting your WSGI server. Also check if there are no WSGI processes stucked in background.
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/
NOTE: THE SPECIFIC QUESTION IS AT THE END BELOW. FIRST I DESCRIBE ALL THE STEPS I WENT THROUGH :-) )
Im using Python 2.7 and Django 4.2.1
on Windows.
I am creating a project called "mysite" which is the project used at docs.djangoproject.com.
So far, I have done the following just like in the tutorial:
1)typed: django-admin.py startproject mysite
This created all the standard folders, which are:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
2) typed: manage.py runserver
and when typing http://127.0.0.1:8000 in the address bar I got a congratulations message.
So far, so good..
3) Then I edited the settings.py file. First I edited the DATABASE ENGINE and typed the following:
'django.db.backends.sqlite3'
4) Still in settings.py, I indicated a DATABASE name so that it creates a database file. I called it:
'mysitedb'
5) Then I synced the database (to create the tables) by typing:
manage.py syncdb
6) Then the tutorial asks to create an app called polls. So I typed:
manage.py startapp polls
That created the following folder and files:
polls/
__init__.py
admin.py
models.py
tests.py
views.py
7) The tutorial then asks to edit the models.py by typing the following:
from django.db import models
import datetime
from django.utils import timezone
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
8) Moving along, I then I had to edit the INSTALLED_APPS section in the settings.py file by typing the following:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
)
9) Then I typed the following to create tables and their fields (I guess..):
manage.py sql polls
then the following printed out:
BEGIN;
CREATE TABLE "polls_poll" (
"id" integer NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL,
"pub_date" datetime NOT NULL
);
CREATE TABLE "polls_choice" (
"id" integer NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
COMMIT;
10) Then I had to type this to create the tables (sync):
manage.py syncdb
So far, still so good..
10) Then they suggest I run python shell in command and play with the database API. At that point everything was working fine. Could add data in the tables' fields, etc.
But here is where it doesn't work. From PART 2 of the tutorial. I have to runserver again (I did that: manage.py runserver, and it worked fine..).
I opened a browser webpage and typed http://127.0.0.1:8000/admin/ and I get the same "It worked! Congratulations on your first Django-powered page..."
No error message. So how do I get the admin page with user logins (username and password) to appear?
Any help will be appreciated.
Thanks!
Usually when the admin in Django isn't working the two main culprits are forgetting to add the following two lines to the urls.py file.
admin.autodiscover()
and
url(r'^admin/', include(admin.site.urls))
Now you can go ahead with the tutorial and when you register models in your admin.py, don't forget
admin.site.register(MyModelGoesHere, MyModelAdminNameGoesHere)
Good luck! :)
I'm trying to implement orderedmodel from here: https://github.com/kirelagin/django-orderedmodel
But it fail with DatabaseError Exception Value: no such column: qrgame_place.order
The documentation says nothing about that the model should contain the field order so I suppose the parent class is supposed to implement that field? [EDIT: Yeah, it is. Tried that...]
Here are some of the important snippets from the django files:
# models.py
import hashlib
import random
from django.db import models
from orderedmodel import OrderedModel
class Place(OrderedModel):
name = models.CharField(max_length=100)
clue = models.CharField(max_length=300)
code = models.CharField(max_length=7, editable=False)
def __unicode__(self):
return self.name
def save(self):
# Need a secret identifier for url. Using a hashed name (which
# is also secret until found. So no need to obscure more)
if not self.id:
hashsrc = self.name.encode('utf-8')
self.code = unicode(hashlib.sha1(hashsrc).hexdigest()[:7])
super(Place, self).save()
# admin.py
from django.contrib import admin
from qrgame.models import Place
from orderedmodel import OrderedModelAdmin
class PlaceAdmin(OrderedModelAdmin):
list_display = ['name', 'clue', 'reorder']
admin.site.register(Place, PlaceAdmin)
# settings.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'orderedmodel',
'qrgame',
)
I have ran python manage.py syncdb after implemented this.
Any idea what's wrong? (Django version is (1, 4, 1, 'final', 0))
syncdb can't alter existing tables at the moment. You can do the following:
drop table manually and than run syncdb
run manage.py reset qrgame but all data of the qrgame app will be lost
use any existing django db migration solutions, like South
manually add column to the table (hints: manage.py dbshell will give you db REPL. You can get column definition from manage.py sqlall qrgame
dumpdata and loaddata commands can be helpful for saving and restoring existing data between schema changes