32
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

既存のDjangoのアプリケーション名を変更する

Last updated at Posted at 2020-02-13

これは何?

普段Djangoで開発していて、たまに思うことがあるかもしれません。

今問題なく動いているんだけど、アプリケーション名がちょっと気に食わない。

試しにただフォルダ名を変更してみると、不要なテーブルが出来てしまい、既存のデータも使えません。

「既存のテーブルに入っているデータはそのまま使いつつ、アプリケーション名を変更したい」という時に何をすればいいのか

色々な方法があると思いますが、そのうちの一つとしてまとめました。

結論

stack overflow/How to change the name of a Django app?
ここに書いている通りです。

  1. フォルダ名を変更する
  2. AppConfigを変更, settingsのINSTALLED_APPSを変更する
  3. アプリケーション名変更前のテーブルを新しいアプリケーション名に合わせてrenameする
  4. django_content_typeとdjango_migrationsを書き換える

の4ステップで既存のコードやレコードはそのままにアプリケーション名を変更することが出来ました。

なぜ上記のステップが必要なのか。

なぜフォルダ名を変更しただけでは想定通りの動きをしてくれないのかを簡単に書きます。

Djangoのmigrationは、django_migrationsテーブルで管理されています。(Sequel Proを使っています)
↓django_migrations
image.png

appカラムはsettings.pyINSTALLED_APPS
nameカラムは各アプリケーションのmigrations内のファイル名が入っています。

また、Modelはdjango_content_typeテーブルで管理されています。
↓django_content_type
image.png

app_labelカラムは同様にsettings.pyINSTALLED_APPS
modelカラムは各アプリケーション内のmodels.pyのモデル名が入っています。

フォルダ名を変更したとしても、これらがそのままだと、Djangoから新しい全く違うアプリケーションが作成されたと認識されてしまいます。

上記の3, 4のステップを踏むことで、Djangoにrenameしたアプリケーションを元からあるものだと認識してもらう必要があります。

下では手を動かした過程を書いています。
興味のある方は是非読んでみてください。


前提

作った blogs appvlogs app に renameしたくなったとします。

blogs appを作ります。

1: Django projectを作成

$ django-admin startproject my-site

2: blogs app を作成

$ python manage.py startapp blogs

3: PostModelを作成

blogs/models.py

from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=255)

4: migrationを走らせる
my-site/settings.py

INSTALLED_APPS = [
    'blogs.apps.BlogsConfig',
    ...
]
$ python manage.py migrate

こうするとこのようなテーブルが作られます。
image.png

ここから blogsvlogsに変更します。

1.フォルダ名を変更する

試しにフォルダ名を変更するだけだとどうなるのかを紹介します。

/blogs/vlogs とします。
この状態で

$ python manage.py migrate

とするともちろん
ModuleNotFoundError: No module named 'blogs'
となります。

では次です。

2. AppConfigを変更, settingsのINSTALLED_APPSを変更する

1で怒られてしまったように、INSTALLED_APPSを編集しなければいけません。

vlogs/apps.py

from django.apps import AppConfig


class VlogsConfig(AppConfig):
    name = 'vlogs'

settings.py


INSTALLED_APPS = [
    'vlogs.apps.VlogsConfig',
    ...
]

これでDjangoがvlogs appを認識してくれるようになるはずです。
showmigrationsを実行します

$ python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial
vlogs
 [ ] 0001_initial

認識されていますね。migrateします。

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, vlogs
Running migrations:
  Applying vlogs.0001_initial... OK

このようにうまく実行されますが、
image.png
vlogs_postblogs_postが出来てしまいます。
理想はvlogs_postだけになっていることです。
ではblogs_postvlogs_postに変更します。

3. アプリケーション名変更前のテーブルを新しいアプリケーション名に合わせてrenameする

PostModelから作られるテーブルはblogs appvlogs appにrenameすることでvlogs_postになって欲しいです。
テーブル名を変更します。

mysql> ALTER TABLE blogs_post RENAME TO vlogs_post;

4. django_content_typeとdjango_migrationsを書き換える

今までblogsとして扱っていたアプリケーションを今後はvlogsとして扱ってもらうために
django_content_typedjango_migrationsを書き換えます。

mysql> UPDATE django_content_type SET app_label='vlogs' WHERE app_label='blogs'
mysql> UPDATE django_migrations SET app='vlogs' WHERE app='blogs'

結果

では、問題ないかどうかを確認します。
確認の方法としては

1: Modelに変更を加えずにmigrateを実行した時に何も起こらないこと

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, vlogs
Running migrations:
  No migrations to apply.

image.png
問題なさそうですね。

2: Modelに変更を加えた時に続きからmigrationが作成されること
Postモデルにcontentカラムを追加します。
vlogs/models.py


from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=255, null=True)

$ python manage.py makemigrations
Migrations for 'vlogs':
  vlogs/migrations/0002_post_content.py
    - Add field content to post

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, vlogs
Running migrations:
  Applying vlogs.0002_post_content... OK

image.png

このようにvlogs/migrations配下に0002_post_content.pyが続きとして作成されcontentカラムが問題なく追加されました。

まとめ

Djangoのmigrationが何を見て動いているのかをなんとなく理解するのに良いお題だと思いました。
普段あまり意識することのないdjango_content_typeにも触れられました。

一応GitHubです。

ありがとうございました。

参考

32
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?