Moving multiple models from one django app to another - django

I'm building a project using django v2.0.2 that consists of 3 apps with 24 models. One of the apps has 14 models. Having so many models in one app is becoming complicated, and I'd like to create a new app and move few models to this app.
I found an answer explaining how this can be done using south. I've been using django core migrations and since south is deprecated, I don't want to switch to south at this point.
The models I want to move are quite complex - they have ForeignKey fields, ManyToMany fields, etc. I need a workflow showing how I can move these models using django core migrations.

That shouldn't be too difficult to do. The main issue you run into is that Django automatically derives the name of the database table from the name of your model class and the app that contains it.
That means unless you're explicitly setting the db_table property in the model meta, the names of all the tables corresponding to your models are auto generated based on app/model name combo.
So if you have a Post model in a Blog app, the auto generated table name of that Post model is blog_post. And if you decide to move Post model to the Article app, Django will be looking for a table named article_post and won't be able to associate your model with the correct table.
To solve this issue, you need to explicitly set the db_table property on each of the models. The db_table name value will have to correspond to the current app/model combo. So in the case of Post model mentioned above, you would set db_table to blog_post. Once you set the db_table property, you can move the model to any other apps.
class Post(models.Model):
title = models.CharField(max_length=120)
class Meta:
db_table = 'blog_post'
Once you move all the models around, login to django admin to verify that your data is still accessible through the newly moved models.
When you run makemigrations for the first time after moving the models,
Django migrations will create migration files that deletes the moved models in their old app and recreate them in their new app. Do not apply these migrations and instead run migrate --fake which will record the migrations as having been executed without making any of the database changes. After that, your migration files and your database structure will be synced.

Related

Why does Django create migrations in the parent model's app when they are inherited?

I have the following setup, an external dependency dep is installed and being used in my Django project and I'm extending one of it's models in my own apps, like the following:
from dep.models import ParentModel
class MyModel(ParentModel):
# fields
Both mine and the dependency models are not abstract and by running makemigrations a new migration is created into the dep app, following it's current migration tree.
The problem is that I expect to have a new migration in my own app as it doesn't make sense to mess with the dependency's migration structure as it's gonna create all sorts of problems whenever it's updated.
Is there a way to go around this?
I've tried moving the migrations manually to my app but when I run makemigrations again, it gets deleted and created again the same way as I mentioned above.
I actually figured it out and the point is that the inherited model's Meta class has the app_label explicitly set which is also inherited by my model, forcing it to be a migration on the same app.
To fix it, I just had to set the same attributes in my model and now the migration is created as I expected.
Here's the example of the base model and mine:
class ParentModel(models.Model):
class Meta:
app_label = "dep"
class MyModel(ParentModel):
class Meta:
app_label = "my_app"

Migrate models outside current app

I'm using django-modeltranslation in a Django 1.8 project. This app generates fields on the fly to store translations. It's possible to mark models as translatable by creating an Options class, like registering models with the Django admin.
I marked a model from a third party app as translatable. Django's migrations system picks up the changes and generates migrations in the app outside of my project. I want to store these migrations in an app in my project, how can I do that? I can only give a model name to migration operations, not a fully qualified app name.model name string.

Using existing NDB on Google App Engine after converting from Webapp2 to Django

I am in the process of converting a Webapp2 app to Django on Google App Engine. Everything is relatively straightforward, and the models have been converted from the webapp models to the django equivalents.
However, I feel this may be have been glossed over in the posts from the app engine team Refering This... Do I need to perform a data migration in order to re-use existing data, or can I simply use the existing NDB models somehow? (If so, what configurations are needed? I can't seem to figure this out).
there is no concept of a data migration in schemaless databases.
A migration that you think of is really creation or alteration of a database schema i.e the DB needs to have a schema only then would the idea of a migration make sense.
After looking into this a little further, I noticed that by default GAE would create db_tables with the default names as <app_label>_<model_name> (i.e. coreapp_GuestBook).
As a result, if you specify the model meta options in Django, matching the converted apps name with the original apps name, you will be able to access the same models with Django. Note that the field values may be inaccessible or possible corrupted if you did not do the conversion of webapp fields to the appropriate Django fields one for one.
See reference: https://cloud.google.com/appengine/articles/django-nonrel
For example, in my case, the Article app would be retrieved by specifying:
class Article(models.Model):
title = models.CharField(max_length=255)
class Meta:
db_table = 'Article'
verbose_name = 'Article'
verbose_name_plural = 'Articles'

Django manytomany field failing with "relation does not exist" due to model being in separate app. Change order of app creation?

I have a model in an app (we'll call it Report) that is referencing a manytomany on another model in a separate app (Notes). When I run manage.py syncdb I keep getting the error relation does not exist because the database table for the Notes model hasn't been created yet. Is there a way to control the order in which syncdb will create database table to fix this problem? My first guess was the ordering of the apps in installed_apps but Notes is definitely before the Report in installed_apps.
Check for, and resolve, any circular imports. This is when one models.py imports from another which also imports from the original. For example, App Report imports models from Notes, but Notes also imports from Report. The only way to change the order of creation, is to change the order of the INSTALLED_APPS and the order in which they are in the models.py files. As jpic said, you can reference the M2M reference object with quotes and the app name dot model name, like:
class Report(models.Model):
.
.
.
whatevers = ManyToManyField('Notes.whatever_model')
.
.
.

South does not recognize models when it is a package

I use South for schema and data migraton for my Django site. I'm happy about using it. One day I converted models.py file to models/__init__py and put some additional models at models/something.py. When I ran python manage.py schemamigration app --auto, I got the Nothing seems to have changed. message despite of the new classes at something.py. If I copied them to the __init__py file, South had recognized the new models. I tried to import everything from something in the top of __init__py, but no change.
It's Django design. Django is not picking your models at all, you need to set app_label in your model's Meta class.
See ticket on Automatically discover models within a package without using the app_label Meta attribute.