So I successfully migrated from a profile model to an extended User model. The data migration all worked fine, but I can't access my users from the admin, I get the following error:
DatabaseError: (1146, "Table 'mydb.app_myuser_groups' doesn't exist")
All I have defined in models.py is the following:
class MyUser(AbstractUser):
isSpecial = models.BooleanField(default=True)
having followed these instructions. Is there more I need to do to get this to work?
See my previous answer here and modify step 4 to look like this:
# encoding: utf-8
from south.db import db
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
# Fill in the destination name with the table name of your model
db.rename_table('auth_user', 'accounts_user')
db.rename_table('auth_user_groups', 'accounts_user_groups')
def backwards(self, orm):
db.rename_table('accounts_user', 'auth_user')
db.rename_table('accounts_user_groups', 'auth_user_groups')
models = { ....... } # Leave this alone
AbstractUser inherits from PermissionMixin, which has a ManyToManyField to the Group model. So there should be a app_myuser_groups table in the database. South may be able to create the intermediate table, but I don't know how. What I know is that syncdbing after having removed app_myuser should work, even though your migration would be shredded.
This question about adding a through table in a migration should give you more insight.
Related
I created a custom user model just like the docs said, when I ran the makemigrations I went to the folder of migrations and deleted the first name and last name columns inside the 0001_initial.py and then I ran the migrate command, but when I ran the createsuperuser command it throwed an error in the terminal that django.db.utils.OperationalError: no such column: myapp_usermodel.first_name
How can I fix this?
I want to delete the first name and last name columns because I'm not using them
EDIT: this is the user model
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractUser
# Create your models here.
class usermodel(AbstractUser):
email = models.EmailField(max_length=60)
username = models.CharField(max_length=20, unique=True)
password = models.CharField(max_length=20)
def __str__(self):
return self.username
I went to the folder of migrations and deleted the first name and last name columns inside the 0001_initial.py
You shouldn't do that. This will indeed prevent Django from creating the columns. But now it will each time query under the impression that the columns are there. Furthermore if you make migrations again, it will try to add extra columns.
You should simply use the method resolution order (MRO) and set the field to None:
class usermodel(AbstractUser):
first_name = None
last_name = None
def __str__(self):
return self.username
You probably also better remove the table in the database and the migration file and make migrations again, and migrate the database.
After customizing my user model in Django Oscar, I received the following error message:
IntegrityError at /
insert or update on table "basket_basket" violates foreign key constraint "basket_basket_owner_id_74ddb970811da304_fk_auth_user_id"
DETAIL: Key (owner_id)=(5) is not present in table "auth_user".
To customize my user model, I followed the instructions here.
First, I wrote the following models.py file, located within my project directory at apps/user/models.py.
from django.db import models
from oscar.apps.customer.abstract_models import AbstractUser
from django.contrib.postgres.fields import ArrayField
class User(AbstractUser):
acct_bal = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
purchased_items = ArrayField(models.IntegerField(), default=list)
The idea is that I want the user to have an account balance (which I will use for payment later) as well as a list of product numbers representing items that have already been purchased.
After making models.py, I edited the installed apps as follows:
INSTALLED_APPS = [...
'shopworld.apps.user',
] + get_core_apps()
And then put this at the bottom of my settings.py:
AUTH_USER_MODEL = 'user.User'
I then did ./manage.py migrate, but for some reason I am getting this error message. I also tried dropping the django_admin_log table as suggested here, but it did not work. Any help would be greatly appreciated.
I fixed this - the issue was that I was trying to migrate to a custom user model after already having done migrations with auth_user. This meant that auth_user didn't update correctly. I had to flush and re-sync the database, so that the initial migration captured the custom user model.
I created a data model in Django which has many to one relation (N topics to 1 user) like this:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
content = models.CharField(max_length=2000)
pub_date = models.DateTimeField('date published')
author = models.ForeignKey(User)
When I try to load the data model in the admin page, I get this error:
Exception Value:
no such column: talk_comment.author_id
Did I miss something in the data model?
Thanks.
You forgot to actually modify/create the tables in database (manually, with South or manage.py syncdb).
You can't modify the table with syncdb . you need to use South Migrations
Its really very good and you can even revert back to previous migration in case of some problem
I’m trying to migrate a few models from one Django app to another and based on this question How do I migrate a model out of one django app and into a new one? I’ve got it pretty much worked but when creating the first migration I’m getting this error:
"The model 'contenttype' from the app 'contenttypes' is not available in this migration."
Google and SO doesn’t seem to find any cases for this happening and the aforementioned question doesn’t have anything specific to say about it either, except the comment in the code:
if not db.dry_run:
# For permissions to work properly after migrating
orm['contenttypes.contenttype'].objects.filter(app_label='common', model='cat').update(app_label='specific')
Would really appreciate any insight into what am I doing wrong.
Here are the two migration files:
Create:
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
db.rename_table('cars_country', 'general_country')
if not db.dry_run:
# For permissions to work properly after migrating
orm['contenttypes.ContentType'].objects.filter(app_label='cars', model='country').update(app_label='general')
def backwards(self, orm):
pass
Delete:
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
depends_on = (
('general', '0002_create_country'),
)
def forwards(self, orm):
db.alter_column('cars_club', 'country_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['general.Country'], null=True))
def backwards(self, orm):
db.rename_table('general_country', 'cars_country')
db.alter_column('cars_club', 'country_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cars.Country'], null=True))
Ok, found the solution. The freezing notice from dgel got me checking the South documentation and there’s a notice about the ORM migration: This is accomplished by serialising the models into a large dictionary called models at the bottom of every migration. It’s easy to see; it’s the large chunk of dense code at the bottom.
So basically I just needed to move the orm['contenttypes.contenttype] to the second migration file, as the contenttype models dictionary was already there. And now everything seems to work as it should.
I have a models folder that has a few models in files that are already in the DB. I have just added another file/model but it is not being added to the DB when I run syncdb. I've tried manage.py validate and it is running fine. I have also run the code and it only fails when it tries to save with "table does not exist".
the original structure was like this:
/models
-- __init__.py
-- file1.py
-- file2.py
and __init__.py looked like:
from file1 import File1Model
from file2 import File2Model
I added file3.py
/models
-- __init__.py
-- file1.py
-- file2.py
-- file3.py
and modified __init__.py
from file1 import File1Model
from file2 import File2Model
from file3 import File3Model
And the contents of file3 (names may have been changed to protect the innocent, but besides that its the exact file):
UPDATE: just tried adding a primary key since the id field may have been messing with the automatically added integer primary key id. Also tried a few variations but no dice.
from django.db import models
from django.contrib.auth.models import User
class File3Model(models.Model):
user = models.OneToOneField(User)
token = models.CharField(max_length=255, blank=False, null=False)
id = models.CharField(primary_key=True, max_length=255)
class Admin:
pass
class Meta:
app_label = 'coolabel'
def __unicode__(self):
return self.user.username
#staticmethod
def getinstance(user, token, id):
try:
instance = File3Model.objects.get(pk=id)
if instance.token != token:
instance.token = token
instance.save()
return instance
except:
pass
instance = File3Model()
instance.user = user
instance.token = token
instance.id = id
instance.save()
return instance
So in this example, File1Model and File2Model are already in the DB and remain in the DB after syncdb. However, File3Model is not added even after rerunning syncdb. Is there any way to figure out why the new model isn't being added??
If you define the model outside of models.py, you have to set the app_label attribute on the models Meta class.
Edit: The app_label has to refer to an app in your INSTALLED_APPS setting. It should probably match the name of the app that the models directory is in, unless you've got a really good reason to do otherwise. That seems to have been your problem here.
class File3Model(models.Model):
foo = models.CharField(...)
...
class Meta:
app_label = "my_app"
Note that syncdb will never remove any tables from the db. The other tables were probably created with syncdb before the models.py was replaced with the directory structure.
set app_label to my app solves my problem.
Why did you split you models and having models folder instead of placing models in models.py ?
In my own project there are about 10 models live in models.py and I'm fine with it.
You can also try manage.py syncdb --all.
And I think its better to keep all models in one single file and import them like from my_app.models import model_name instead of keeping in mind to import necessary model into models/__init__.py. By the way you avoid many problems and long lined imports and don't care about where some_model lives among models/*.py files.
Thanks,
Sultan
BOOM!
I was using a different app_label for the new model but it has to be the same across the model group.
The other models labels were "mediocrelabel" and my new model had the label "coolabel". I changed the new model's label to "mediocrelabel" and now they are being added to the DB correctly.
Thanks for your help, folks!