I created a custom user model in Django and it worked up fine. However, I decided to create a custom model to suit my needs after the project was up and running.
As a result, I will need to migrate the schema (Currently, when I register a user, the code is still referencing to the the auth_user database tables where as the new custom user table is user.)
I have set the AUTH_USER_MODEL in settings.py to userapp.User, where userapp is my custom user app and User is the Model that inherits from the AbstractUser model.
I am fairly new to Django and cannot understand how to achieve this. One obvious way to clean install the database, which is not something that I'm looking to do as it will remove all my data.
How do I migrate then? I've heard South is used for that but I don't know how to use it. Besides I think South isn't required in the recent versions of Django.
My version of Django is 1.8.2.
I did this recently - we used a data migration to move between the two models. Rough steps:
Create the new user model (without telling Django about it), make/apply migrations to create the database table(s)
Write a the data-migration to copy the data over to the new user model. Then run this migration and update Django to use the new model
Now you should be switched over, and can delete/archive the old auth_user table as needed
Related
I have a DB (lets call it data_db) containing some tables. I want to create a dashboard to present data from data_db, so I created a Django project for that purpose.
When I want to get data from one of the tables in data_db, is there a way to do it with Models? (I want Django security management with the DB) or do I have to use raw SQL?
One note: there is existing data in the data_db's table, and I don't want to create a new table with the same exact data on the default Django DB. I also use 2 DBs, Django default's and data_db and I created a database router for data_db to prevent Django from creating all its tables in there.
Thanks.
Yes. In fact Django can even help you create the models. Models that you do not migrate with the help of Django are unmanaged models. These have a managed = False attribute in the Meta class, so something like:
class MyModel(models.Model):
# … fields …
class Meta:
managed = False
If you thus write these unmanaged models, you can make queries with the Django ORM, without Django trying to create new models for these tables.
Of course, specifying models that match with the database is cumbersome. Therefore Django can often construct models based on the tables. You can generate the models with the inspectdb command [Django-doc].
You can generate these models on the stdout with:
python3 manage.py inspectdb
or you can save these to a file through I/O redirection:
python3 manage.py inspectdb > app_name/models.py
I have created a UserProfile field in order to add a favorites functionality to my site. Using Django's recommendation, I created a UserProfile model as follows at the bottom
Unfortunately, I already had the rest of my database created, and so I need to either use a migration utility or manually edit my database. However, I do not have sufficient permissions to utilize a migration utility, so I have to edit the database directly, and am struggling to do so.
This answer is similar to what I want to accomplish, but I can't quite get the syntax to work in my case.
MySQL - One To One Relation?
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
favorites = models.ManyToManyField(Media, related_name='favorited_by')
In my experience, the best migration utility is South. Once you've installed and added it to your settings, you'll need to create initial migrations for your existing modules using
./manage.py schemamigration --initial my_module,
which will include the one containing your UserProfile model, then from there you can migrate using
manage.py migrate my_module.
The real power in using a utility like this is portability and reversibility. You can migrate forward and backward as needed, and you'll be able to bring your schema to virtually any SQL database without all the fuss of rebuilding using SQL directly.
I would certainly agree with Steves recommendation to use South.
However if you for some reason wouldn't want to, you can issue the following command:
python manage.py sql <appname>
This will output the SQL statements which django will use to create your tables. This can then be used to manually modify the database.
I need to add a couple fields to Group model in django contrib.auth app using:
field_name = models.CharField(...)
field_name.contribute_to_class(Group, 'field_name')
My issue is while creating the migrations with South, since they are created in the "migrations" directory inside the auth app and, since the system is already in production, I'm not allowed to alter the current django installation in the server in order to migrate auth.
Does anyone know how to create and load such migrations?
Thanks in advance for your help.
Django doesn't make it particularly easy to modify the standard models. I wouldn't recommend that you sublass Group, because it's quite annoying to get built-in functionality to reference the new model instead.
The usual thing to do here is to create a GroupProfile model that has a Group as a unique foreign key. It might not be elegant, but it won't have the huge maintenance overhead that comes with forking Django's source code.
Also: if you can't modify the Django code on the server, you aren't going to be able to do this with raw SQL hackery or a clever migration. South isn't going to be the problem -- the problem is that the Django ORM is going to notice that there are fields present in the SQL table that aren't specified in the code, which will cause it to throw an exception.
Since you use a hack to patch up the model, I think you should write a migration manually. Try copying another migration and changing add_column and models first, if it fails - there is always an option named "raw sql" :)
I have some models I'm working with in a new Django installation. Is it possible to change the fields without losing app data?
I tried changing the field and running python manage.py syncdb. There was no output from this command.
Renavigating to admin pages for editing the changed models caused TemplateSyntaxErrors as Django sought to display fields that didn't exist in the db.
I am using SQLite.
I am able to delete the db file, then re-run python manage.py syncdb, but that is kind of a pain. Is there a better way to do it?
Django does not ever alter an existing database column. Syncdb will create tables, but it does not do 'migrations' as found in Rails, for instance. If you need something like that, check out Django South.
See the docs for syndb:
Syncdb will not alter existing tables
syncdb will only create tables for models which have not yet been installed. It will never issue ALTER TABLE statements to match changes made to a model class after installation. Changes to model classes and database schemas often involve some form of ambiguity and, in those cases, Django would have to guess at the correct changes to make. There is a risk that critical data would be lost in the process.
If you have made changes to a model and wish to alter the database tables to match, use the sql command to display the new SQL structure and compare that to your existing table schema to work out the changes.
You have to change the column names in your DB manually through whatever administration tools sqlite provides. I've done this with MySQL, for instance, and since MySQL lets you change column names without affecting your data, it's no problem.
Of course there is.
Check out South
You'll have to manually update the database schema/layout, if you're only talking about adding/removing columns.
If you're attempting to rename a column, you'll have to find another way.
You can use the python manage.py sql [app name] (http://docs.djangoproject.com/en/dev/ref/django-admin/#sql-appname-appname) command to see what the new SQL should look like, to see what columns, of what type/specification Django would have you add, and then manually run corresponding ALTER TABLE commands.
There are some apps/projects that enable easier model/DB management, but Django doesn't support this out of the box, on purpose/by design.
I added some models in my models.py and I want to add an admin class to use a wysiwyg-editor in text-fields.
Well, I know that Django itself doesn't support migrations and I've used South, but it doesn't work either.
South doesn't "see" the change.
Could it be, that South just detects changes to fields, but not if I add a new class?
How can I tweak Django to detect such changes?
syncdb and South are only concerned with descendants of Model in apps listed in INSTALLED_APPS. Everything else is handled by Django directly.
You seem to be very confused, unfortunately. Of course Django reads the code in models.py - otherwise what would be the point of it? Django uses that code initially to define the model SQL when doing syncdb, but it doesn't modify existing database tables in subsequent calls to syncdb - hence the need for South.
But naturally, Django uses models.py and admin.py and all the other Python code to define its own configuration and state. (And note that admin classes are not defined in models.py but in admin.py.)
If you are not seeing changes, you will need to restart your server.
I'm fairly sure that if you follow the steps as outlined in the tutorial to create an admin app it'll just work. Migration isn't an issue as the admin app creates new tables rather than altering the existing one.