Aidas Bendoraitis, автор книги «Django 3 Web Development Cookbook», рассказал, как переименовать приложение в Django.
Когда я начал работу над MVP (минимально жизнеспособным продуктом) моего проекта 1st things 1st, я сперва думал, что этот Django-проект будет посвящен приоритизации. Несколько лет спустя я понял, что этот проект по сути SaaS (software as a service, ПО как услуга), а приоритизация — лишь часть необходимого функционала для SaaS. В конечном итоге мне понадобилось переименовать приложение, чтобы получить более чистый и лучше организованный код. Вот как я это сделал.
0. Обновите ваш код и кодовую базу
Убедитесь, что вы сделали git pull последних изменений и выполнили все миграции базы данных.
[python_ad_block]
1. Установите django-rename-app
Поместите django-rename-app
в pip requirements и установите его. Либо просто запустите следующую команду:
(venv)$ pip install django-rename-app
Внесите это приложение в INSTALLED_APPS в ваших настройках:
INSTALLED_APPS = [ # … "django_rename_app", ]
2. Переименуйте директории приложения
Смените старое имя (oldapp
) на новое (newapp
) в ваших приложениях и шаблонах.
3. Измените имя приложения там, где оно встречается в коде
Измените имя во всех ваших импортах, миграциях и путях шаблонов.
Можно сделать глобальный поиск oldapp
, а затем перебрать все результаты.
4. Запустите управляющую команду rename_app
Выполните следующую команду:
(env)$ python manage.py rename_app oldapp newapp
Эта команда заменит префикс имени в таблицах приложения и записях в таблицах django_content_type
и django_migrations
.
Если планируете обновить сервера стейджинга и продакшена, добавьте команду rename_app
перед запуском миграций в своих скриптах деплоймента (Ansible, Docker и т.п..).
5. Обновите индексы и ограничения
Наконец, создайте пустую миграцию базы данных для приложения с пользовательским кодом, чтобы обновить индексы и ограничения внешних ключей.
(env)$ python manage.py makemigrations newapp --empty --name rename_indexes
Заполните миграцию следующим кодом:
# newapp/migrations/0002_rename_indexes.py from django.db import migrations def named_tuple_fetch_all(cursor): "Return all rows from a cursor as a namedtuple" from collections import namedtuple desc = cursor.description Result = namedtuple("Result", [col[0] for col in desc]) return [Result(*row) for row in cursor.fetchall()] def rename_indexes(apps, schema_editor): from django.db import connection with connection.cursor() as cursor: cursor.execute( """SELECT indexname FROM pg_indexes WHERE tablename LIKE 'newapp%'""" ) for result in named_tuple_fetch_all(cursor): old_index_name = result.indexname new_index_name = old_index_name.replace( "oldapp_", "newapp_", 1 ) cursor.execute( f"""ALTER INDEX IF EXISTS {old_index_name} RENAME TO {new_index_name}""" ) def rename_foreignkeys(apps, schema_editor): from django.db import connection with connection.cursor() as cursor: cursor.execute( """SELECT table_name, constraint_name FROM information_schema.key_column_usage WHERE constraint_catalog=CURRENT_CATALOG AND table_name LIKE 'newapp%' AND position_in_unique_constraint notnull""" ) for result in named_tuple_fetch_all(cursor): table_name = result.table_name old_foreignkey_name = result.constraint_name new_foreignkey_name = old_foreignkey_name.replace( "oldapp_", "newapp_", 1 ) cursor.execute( f"""ALTER TABLE {table_name} RENAME CONSTRAINT {old_foreignkey_name} TO {new_foreignkey_name}""" ) class Migration(migrations.Migration): dependencies = [ ("newapp", "0001_initial"), ] operations = [ migrations.RunPython(rename_indexes, migrations.RunPython.noop), migrations.RunPython(rename_foreignkeys, migrations.RunPython.noop), ]
Запустите миграции:
(env)$ python manage.py migrate
Если что-то не работает так, как ожидалось, мигрируйте обратно, исправьте код и затем снова мигрируйте. Отменить миграцию можно путем миграции на один шаг до последней миграции. Например:
(env)$ python manage.py migrate 0001
6. Уборка
После применения миграции во всех необходимых окружениях можно подчистить их путем удаления django-rename-app из pip requirements и скриптов деплоймента.
Итоги
Редко удается построить систему, которая изначально будет отвечать всем вашим нуждам. Системы всегда требуют постоянного улучшения и рефакторинга. Используя миграции Django и django-rename-app, можно работать над сайтами в стиле Agile, чисто и гибко.
Перевод статьи «How to Rename a Django App».
Здравствуйте, уважаемые коллеги.
Когда-то давно передо мной встала проблема определения имени приложения в админке Django. Как вы знаете, django.contrib.admin выводит в своём интерфейсе англоязычные имена для applications в виде заголовков блоков, в которых, собственно, расположены страницы самих моделей.
Собственно, увидев такой вариант оформления панели, один из заказчиков попросил хотя бы для основных управляемых элементов (а их было не так уж мало) перевести заголовки на русский язык.
Так начались поиски ответа на вопрос: «Как поменять название приложения в админке Django». Как оказалось, вопрос был не совсем точным, поскольку во фреймворке уже имелось встроенное решение. Документация Django подсказала, что в модели можно переопределить свойство app_label в классе Meta.
Вот источник.
А вот пример кода:
class Entry(models.Model):
# Тут поля...
class Meta:
app_label = 'my_blog'
У этого метода есть серьёзный недостаток: app_label используется Django ещё и для именования таблиц в базе данных. Так что тут особо не разгуляешься: текст не переведёшь, а ошибка в имени может вызвать долгие романтические отношения с БД.
Решение, которое мне удалось найти — не новое. Оно расположено на code.djangoproject.com. И тут уж я не помню: сам я его допиливал, либо обратился к кому-то за помощью, но в общем, мне удалось получить вот такой сниппет, который я до сих пор вставляю в свои модели:
# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
APPLICATION_NAME = _('Simple Blog') # Читаемое имя приложения
DATABASE_NAME = 'simple_blog' # Общий префикс имени базы данных
# Функция получения имени отдельной таблицы в базе данных по общему префиксу и имени модели
def get_raw_name(raw):
return '{0}_{1}'.format(DATABASE_NAME, raw)
# Special Class for different names of the application
# in admin interface and in the database
class StringWithTitle(str):
def __new__(cls, value, title):
instance = str.__new__(cls, value)
instance._title = title
return instance
def title(self):
return self._title
__copy__ = lambda self: self
__deepcopy__ = lambda self, memodict: self
get_class = lambda x: globals()[x]
Работает это дело просто: при создании структуры таблиц используется переменная value, а для получения выводимой метки — title. В процессе работы возникли проблемы с именами таблиц, так что добавилась функция get_raw_name, а также, две переменные, которые позволили не писать имена БД и приложения в каждой модели.
После внедрения такого сниппета, код моделей должен будет выглядеть так:
class Entry(models.Model):
# Тут поля...
class Meta:
app_label = StringWithTitle(DATABASE_NAME, APPLICATION_NAME)
db_table = get_raw_name('entry')
Итого, мы имеем переопределённое имя приложения и возможность переопределять имя таблицы в базе данных. Второе, кстати, чревато последствиями, поскольку при возникновении связей между таблицами система может рухнуть. Так что, наиболее правильно не прописывать db_table или определять это свойство так, как оно должно выглядеть по-умолчанию.
Как-то в бекенде школы меня перестало устраивать название приложения в Django. Всё просто — когда я начинал проект, я продавал только курсы, и приложение с моделями курсов называлось courses. Потом появились записи этих курсов (record) и наборы (bundles). Конечно мне захотелось переименовать приложение courses в products, чтобы уменьшить когнитивную нагрузку при чтении кода.
К сожалению, я не нашёл ни одного решения, кроме стрёмного django-rename-app, который предлагал мне выполнять management-команды в консольке на проде. Кроме того, что это ломает любые пайплайны CICD, там ещё и код был не очень понятный. Так что в итоге я решил сделать это сам. Оказалось сложно, поэтому я написал эту инструкцию.
Исходные условия:
- CICD пайплайн, который запускает миграции при каждом деплое.
- Данные терять нельзя.
- Мы не стесняемся править старые миграции.
Все изменения я делал на живом проекте, так что примеры будем брать прямо из пулл-реквестов.
- Подменяем имя приложения в истории миграций:
./manage.py makemigrations <some-other-app> -n RenameOldApp --empty
. Коммит. - Деплоим миграцию на прод. После этого шага ничего нельзя деплоить до конца.
- Делаем новый пулл-реквест.
- Переименовываем папку с приложением:
git mv courses products
- Заменяем все упоминания старого приложения в миграциях. Коммит.
- У всех моделей в новом приложения в Meta прописываем
db_table
с именем старого приложения. В моём случае, если модель называется bundle и лежала в приложении courses, нужно прописатьdb_table = 'courses_bundle'
. Коммит. - В старых миграциях, которые используют операцию
CreateTable
, добавляем новуюdb_table
вoptions
. Коммит. - Меняем упоминания приложения в коде, можно автозаменой. Коммит.
- Проверяем,
./manage.py makemigrations --check
. Новых автоматических миграцией был не должно, ошибок тоже. - Деплоим на прод.
В итоге у нас получается два деплоя. Первый подменяет миграции, а второй — код. В результате модели будут лежать по новому адресу, но ходить в старые таблицы. Для меня это было плюсом, т.к. не пришлось переделывать аналитические SQL-запросы, которые ходят в базу из Metabase.
31 Jan 2019
Updating the name of an existing Django App is easier said than done. After you’ve renamed your folder name you will instantly be met with errors and different issues that result from dependencies to the old app name.
Many times the first version of your application is not the final one, and your code base might go through thousands of iterations where you slowly add, remove or change the features of your app.
Sometimes these changes are major refactors which includes migrating code or models from one app to another or renaming existing apps to make more sense in the context of the updated code base.
So how do you avoid these errors? What is it that you are required to do to migrate an application from folder A to folder B or to simply change its name?
Step-by-Step List to Changing App Name
The name of your Django applications are referred to all over the place and there is a list of actions that you have to take to complete the changes.
- Rename the folder of the application you want to update.
- Update any dependencies and import statements to the folder you updated.
- Update database entries for the
django_content_type
table to refer to the new application’sapp_label
. - Update the table names of any models that you haven’t explicitly set the table name of. These table names are inferred by the application name and need to be updated.
- Update database entries for the
django_migrations
table and update the application reference for each migration by setting theapp
field to your new app label. - Update any namespaced folder names that are within your
/static
or/templates
folder. For example, you might have./foo_app/templates/foo_app/index.html
and it should be updated to./bar_app/templates/bar_app/index.html
.
On top of this, if you have also updated your model names or if you’ve updated the folder that contains a virtualenv, you also have to take the additional steps of:
- Rename your Django models within the
django_content_type
table. This is done by updating thename
column to the new model name. - Delete and recreate your virtualenv folder and reinstall all dependencies.
Let’s walk through all of these tasks in more detail to take you through how you do each one.
1. Rename Django App Folder
Renaming the application folder is a very straight forward thing to do. Just… rename it. However, if you use the correct tools it can also simplify and minimize the manual work you have to do to update all the references from the old folder name to the new one.
Become a better Software Engineer or Data Scientist
Get weekly notifications of the latest blog posts with tips and learnings of
how to become a better programmer.
No spam, no advertising, just content.
For example, by using PyCharm you can right click on your folder name and select Refactor->Rename and you will get a popup with some additional options.
Here you can then decide if you want PyCharm to automatically attempt to update any file paths, import paths or other references to the directory automatically.
In a large code base, this might save you a ton of time! Be careful though, if you have applications named common things such as “core”, “app”, “config” etc, PyCharm might make mistakes and update the wrong references.
For example, imagine that you have a Django app named core
and you want to rename it to myapp
. Let’s then say that you have the following code somewhere in your code base.
from django.core.files.storages import default_storage
from core.models import MyCustomModel
...
PyCharm might then rewrite both of these import statements to
from django.myapp.files.storags import default_storage
from myapp.models import MyCustomModel
This rarely happens, but it is something worth to look out for.
2. Update any Dependencies or References
This step is significantly made much easier by following the advice in the previous section to use a tool such as PyCharm.
By using the PyCharm Refactor->Rename action, you can make it automatically update any uses of the application name within your code base and fix any import statements or dependencies.
If you don’t have the access to something like PyCharm, I would attempt to perhaps to it with a Regular Expression, or in the worst case search the whole code base for any usages of the old folder name and update it manually.
Here below you can find a few examples of regular expressions that could be used to find any references to an old application named foo
.
^(from|import)s(foo)
will match any import statement that your old application name is used in.["'](foo)['"]
will match any string value that is the name of your old application.
You can use these regular expressions to then automatically replace any references to your old name with your new name, without having to manually go through each file by yourself.
If you use VSCode or other smart IDE’s that can do Regular Expression Group Match Replacements you could then refer to other pieces of the regular expression and only replace parts of it.
Finally, if your code base is relatively small, or if your application is named with more unique names that might not occur all over the code base in other contexts, you could simply just search for any instance of your old application name and update them manually.
A few good locations to look for when we are talking about references or dependencies would be:
- Import statements
- Models Meta app_name value.
INSTALLED_APPS
settings- Docstrings and other Documentation or texts that refer to applications.
- If you set
app_name
in Models Meta classes or thename
in your application’sAppConfig
, you need to update these to point to the new label.
3. Update Django Content Type Table
By default, you will find the django.contrib.contenttypes
application within the list of INSTALLED_APPS
in your settings.py
file. This is a core application within Django and its used to keep track of the different models and content that is available within your app.
Anytime you add applications and run migrations, this table adds references to the models to the django_content_type
table within your database. Whenever we rename an application or a model, it then also means that we have to update the references from the old application to the new application within this table.
The main query you need to run is the following:
UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>';
Obviously, you should replace the <NewAppName>
and the <OldAppName>
with your own names to be able to run the query successfully. What this query does is that it simply updates all the lines within the table that contain your old app name as the app_label
, to the new app name.
If you have updated any model names within your application, you will also be forced to run a second query to update the name
field of each row within the django_content_type
table.
UPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'
Once again, you should obviously replace the <newModelName>
, <oldModelName>
and <OldAppName>
with your own versions for the query to be executed.
4. Update Model Table Names
If you have any Models in your application (which you probably do) it is fairly common that programmers let Django infer the name of the model table by the name of the application combined with the name of the model.
For example, if our foo
application has a bar
model within it, the automatic table name would become foo_bar
. You can also set this to some explicit value by updating the Meta
class of your model in the following manner:
from django.db import models
class Bar(models.Model):
...
class Meta:
db_table = "custom_bar"
So when it comes to making your models work properly after you’ve updated the app name, you have 2 options:
- Set the
db_table
value for all of your models to refer to the old application name and the existing table name. - Update all the existing table names to match the new application name.
Personally, I prefer the second option, because it makes sense that things are named “properly” instead of having some tables refer to some old application name that doesn’t exist anymore. That could be confusing when new developers join our project and take a look at our database.
The query used to update table names are the following:
ALTER TABLE old_app_model_name RENAME TO new_app_model_name;
You will need to run one of these queries for each of the model tables that you have. To get a list of all your table names you can connect to your database and run dt
on PostgreSQL or desc tables;
on MySQL to get a full list of tables in your database.
5. Update Django Migrations Table to New App Name
Django allows developers to automatically generate migration files that represent changes to the models in Python, that then gets migrated to the selected database and applied as SQL queries.
Each time a migration is applied, Django will need to store the state of the migration so that it never attempts to execute the same migration twice. This is done by storing references to each migration in the django_migrations
table.
The migration table in the database contains references to which application that the migration relates to, this is stored in the app
column. Since we changed our application name, it also means that we will need to update all the references within the django_migrations
table to prevent Django from attempting to re-applying all of our migrations.
This can be achieved with the following query:
UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'
6. Rename Namespaced Folder Names in Static or Template Folders
A common practice in Django is to namespace any static or template file that you have in your application with the name of the application itself. This is done by putting all the files within a directory named by the application.
For example:
- No Namespace:
./foo/static/js/index.js
. - Namespace:
./foo/static/foo/js/index.js
.
What this leads to is that when Django later collect all the static files and dump them in a single folder, it will separate them out by the application. This helps to prevent overrides or naming collisions.
Because of this common practice, we have to make sure that any static/
or /template
folders that exist in our app get updated with the new application name as the namespace.
Because of this, it also means that we should update any references to these files. So anywhere where we load static files or templates from within our templates or python files, we should also properly update it to use the new namespace.
Conclusion
That’s it! You should now be able to run your application again after you have renamed one or more of your Django apps. At times this whole process might feel very frustrating and cumbersome, but we should also remember that all of these things are there to add value to Django.
For example, it might be tiresome to have to update the django_migrations
table with the new app name, but at the same time, the fact that we have a table like that makes our job as programmers so much easier when it comes to migrating database schema changes.
Become a better Software Engineer or Data Scientist
Get weekly notifications of the latest blog posts with tips and learnings of
how to become a better programmer.
No spam, no advertising, just content.
Я изменил имя приложения в Django, переименовав его папку, импорт и все ее ссылки (шаблоны/индексы). Но теперь я получаю эту ошибку, когда пытаюсь запустить python manage.py runserver
Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings
Как я могу отладить и решить эту ошибку? Любые подсказки?
06 дек. 2011, в 21:50
Поделиться
Источник
3 ответа
Чтобы изменить имя приложения в Django, выполните следующие действия:
- Переименуйте папку, которая находится в корневом каталоге проекта
- Измените любые ссылки на ваше приложение в своих зависимостях, то есть файлы приложений
views.py
,urls.py
, ‘manage.py’ иsettings.py
. - Измените таблицу базы данных
django_content_type
следующей командой:UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
- Также, если у вас есть модели, вам придется переименовать таблицы моделей. Для postgres используйте
ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
. Для mysql тоже я думаю, что это то же самое (как упоминалось @null_radix) - (Для Django >= 1.7) Обновите таблицу
django_migrations
, чтобы избежать повторного запуска предыдущих миграций:UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'
. Примечание: есть некоторые дебаты (в комментариях), если этот шаг необходим для Django 1.8+; Если кто-то знает наверняка, пожалуйста, обновите здесь. - Если ваш метатег
models.py
содержитapp_name
, обязательно переименуйте его тоже (упомянутый @will). - Если у вас есть namespaced ваши папки
static
илиtemplates
внутри вашего приложения, вам также нужно будет переименовать их. Например, переименуйтеold_app/static/old_app
вnew_app/static/new_app
. - Для переименования django
models
вам нужно будет изменить записьdjango_content_type.name
в БД. Для postgreSQL используйтеUPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'
Мета-точка (если используется virtualenv): Стоит отметить, что если вы переименовываете каталог, содержащий ваш virtualenv, вероятно, будет несколько файлов в вашем env, которые содержат абсолютный путь, а также понадобятся быть обновленным. Если вы получаете ошибки, такие как ImportError: No module named ...
, это может быть преступником. (благодаря @danyamachine для обеспечения этого).
Другие ссылки:, вы также можете ссылаться на приведенные ниже ссылки для более полного изображения
- Переименование приложения с помощью Django и South
- Как перенести модель из одного приложения django и в новое?
- Как изменить имя приложения Django?
- Обратная миграция с Django South
- Самый простой способ переименовать модель с помощью Django/South?
- код Python (благодаря A.Raouf), чтобы автоматизировать вышеуказанное шаги (неактивный код. Вы были предупреждены!)
- код Python (благодаря rafaponieman), чтобы автоматизировать вышеуказанное шаги (неактивный код. Вы были предупреждены!)
Srikar Appalaraju
06 дек. 2011, в 23:51
Поделиться
Новое в Django 1.7 — это реестр приложений, который хранит конфигурацию и обеспечивает интроспекцию. Этот механизм позволяет изменять несколько атрибутов приложения.
Главное, что я хочу сделать, это то, что переименование приложения не всегда необходимо: при конфигурации приложения можно разрешать конфликтующие приложения. Но и путь, если ваше приложение нуждается в дружественном наименовании.
В качестве примера я хочу назвать свое приложение опросов «Обратная связь с пользователями». Это происходит следующим образом:
Создайте файл apps.py
в каталоге polls
:
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
verbose_name = "Feedback from users"
Добавьте конфигурацию приложения по умолчанию в polls/__init__.py
:
default_app_config = 'polls.apps.PollsConfig'
Для получения дополнительной конфигурации приложения: https://docs.djangoproject.com/en/1.7/ref/applications/
allcaps
01 дек. 2014, в 11:18
Поделиться
Если вы используете PyCharm и останавливаете работу над проектом после переименования:
- Отредактируйте конфигурацию Run/Debug и измените переменную среды DJANGO_SETTINGS_MODULE, так как она включает название вашего проекта.
- Перейдите в Настройки/Языки и Рамки /Django и обновите местоположение файла настроек.
Maziyar Mk
29 сен. 2017, в 19:56
Поделиться
Ещё вопросы
- 0Angular: Как разделить (разделить) скрипт контроллера? [Дубликат]
- 0AngularJS Filter, установить класс метки и поля ввода с проверкой
- 0Перезаписать текущую тему в YII
- 0Получить существующий результат поиска в блоке Magento
- 1Как мне зашифровать App.config для Azure WebJob?
- 1Pandas Group By Условия
- 1Получите глубокий результат обучения между 0 и 1
- 0Блоки кода запускаются с помощью инструментов разработчика Visual C ++
- 0Как получить доступ к переменной из родительского класса
- 0Не удается получить запрос LIKE, чтобы получить результаты записей за 2 и 4 цифры за год
- 0разобрать php код как html используя htaccess
- 0Jquery Dialog добавить пользовательский класс для кнопки
- 0JQuery Автозаполнение проблемы
- 1MinMax Scale Sparse Matrix исключая нулевые элементы
- 0Автообновление внешнего ключа в SQL
- 0SQL Как отобразить текст рядом со значениями в столбце
- 1Я импортировал Selenium, и я думал, что он был установлен с Python, я не могу найти, где это идет не так
- 1EventQueue.invokeLater vs Thread.start
- 1Как изменить свойство переднего плана AvalonDock AnchorablePaneTitle ContentPresenter при автоматическом скрытии?
- 0Symfony 2.6 автоматически переносит дату назад на один день
- 0Компилятор Intel: что означает ошибка «неизвестный тип в IL-обходе»?
- 0установить срок годности элементов, загруженных другими серверами на моем сайте
- 1То же действие по добавлению, но разные результаты в Javascript
- 1Запрос $ ресурса и GridFS
- 0условно в зависимости от стиля
- 0Выровняйте меню вправо, если lithth child равен 1 или 2
- 1Выражение, которое возвращает содержимое между двумя DateTimes в файле журнала, если определенный токен остается между
- 1Как вы не используете карри в Javascript ES6?
- 0CSS3 для печатных СМИ
- 0PHP генерирует категорию и подкатегорию из базы данных [дубликаты]
- 1Динамическое требование Webpack дает ошибку смешанного содержимого
- 0Как составить список неизвестного количества значений [дубликата]
- 1Загрузить файлы из динамического просмотра
- 1OpenLayers: Как я могу перерисовать карту после сворачивания боковой панели?
- 0Камера расширения не найдена — PhoneGap 3.0
- 1Android Support Library управление хранилищем и цикл выпуска
- 0Обновление значений таблицы с использованием раскрывающегося списка без использования кнопки отправки
- 0MySQL сказал: доступ запрещен для пользователя ‘root’ @ ‘localhost’ (с использованием пароля: НЕТ) «
- 1Eclipse 3.5 + ADT: ошибки пути сборки
- 0Вызов контроллера при выборе меню в одностраничном приложении — MVC & angularJs
- 1Как вызвать функцию JavaScript в событии on_change в Odoo
- 0одушевление и исчезновение одновременно — JQuery
- 0Использование Javascript для вычисления полей формы с комбинацией переключателей, текстовых полей и ползунка
- 0Как удалить содержимое div?
- 0как получить внучку от родителя в php
- 1Разбор вывода команды ping
- 0Разбивка на несколько классов div
- 1Воспроизведение сырого PCM с помощью NAudio (выводит шум, но в Audacity открывается нормально)
- 1веб-часы не срабатывают
- 1Реализация Android Action Bar
I agree with Laksham that you should avoid this situation. But sometimes, we have to. I’ve faced this situation in the past and I’ve managed it this way.
If you want to avoid losing data you can dump the old application data into a json file.
python manage.py dumpdata old_app --natural --indent=4 1> old_app.json
Note the —natural option that will force the content types to be exported with their natural keys (app_name, model)
Then you can create a small command to open this json file and to replace all the old_app references with the new_app.
Something like this should work
class Command(BaseCommand):
help = u"Rename app in json dump"
def handle(self, *args, **options):
try:
old_app = args[0]
new_app = args[1]
filename = args[2]
except IndexError:
print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'
return
try:
dump_file = open(filename, 'r')
except IOError:
print filename, u"doesn't exist"
return
objects = json.loads(dump_file.read())
dump_file.close()
for obj in objects:
obj["model"] = obj["model"].replace(old_app, new_app, 1)
if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):
obj["fields"]["content_type"][0] = new_app
dump_file = open(filename, 'w')
dump_file.write(json.dumps(objects, indent=4))
dump_file.close()
Then rename the application, change the name in INSTALLED_APPS.
Then, you should remove all south migrations, regenerate and apply an initial migration for the new app. Then run the SQL command:
update django_content_type set app_label='new_app' where app_label='old_app'
Then launch a south migrate for the new app in order to create the tables and load the json file.
python manage.py loaddata old_app.json
I’ve done something similar on a project and it seems to work ok.
I hope it helps
I agree with Laksham that you should avoid this situation. But sometimes, we have to. I’ve faced this situation in the past and I’ve managed it this way.
If you want to avoid losing data you can dump the old application data into a json file.
python manage.py dumpdata old_app --natural --indent=4 1> old_app.json
Note the —natural option that will force the content types to be exported with their natural keys (app_name, model)
Then you can create a small command to open this json file and to replace all the old_app references with the new_app.
Something like this should work
class Command(BaseCommand):
help = u"Rename app in json dump"
def handle(self, *args, **options):
try:
old_app = args[0]
new_app = args[1]
filename = args[2]
except IndexError:
print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'
return
try:
dump_file = open(filename, 'r')
except IOError:
print filename, u"doesn't exist"
return
objects = json.loads(dump_file.read())
dump_file.close()
for obj in objects:
obj["model"] = obj["model"].replace(old_app, new_app, 1)
if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):
obj["fields"]["content_type"][0] = new_app
dump_file = open(filename, 'w')
dump_file.write(json.dumps(objects, indent=4))
dump_file.close()
Then rename the application, change the name in INSTALLED_APPS.
Then, you should remove all south migrations, regenerate and apply an initial migration for the new app. Then run the SQL command:
update django_content_type set app_label='new_app' where app_label='old_app'
Then launch a south migrate for the new app in order to create the tables and load the json file.
python manage.py loaddata old_app.json
I’ve done something similar on a project and it seems to work ok.
I hope it helps