Como mudar o nome de um aplicativo Django?

156

Mudei o nome de um aplicativo no Django renomeando sua pasta, importações e todas as suas referências (modelos / índices). Mas agora eu recebo esse erro quando tento executarpython manage.py runserver

Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings

Como posso depurar e resolver esse erro? Alguma pista?

André
fonte
Oi danihp. Sim, eu tenho. Também estou usando o virtualenv, não sei se isso tem algo a ver.
André
1
Se, por acaso, você estiver usando PyCharm, seu renamerecurso o ajudará bastante com isso.
Anto
1
O Sul não está suportando essa operação?
18714 Andilabs 17/07

Respostas:

285

Siga estas etapas para alterar o nome de um aplicativo no Django:

  1. Renomeie a pasta que está na raiz do seu projeto
  2. Alterar qualquer referência a sua aplicação em suas dependências, ou seja, do aplicativo views.py, urls.py'manage.py', e settings.pyarquivos.
  3. Edite a tabela do banco de dados django_content_typecom o seguinte comando:UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
  4. Além disso, se você tiver modelos, precisará renomear as tabelas de modelos. Para o postgres, use ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName. Para o mysql também acho que é o mesmo (como mencionado por @null_radix)
  5. (Para Django> = 1,7) Atualizar a django_migrationstabela para evitar ter suas migrações anteriores re-executar: UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'. Nota : há algum debate (nos comentários) se esta etapa é necessária para o Django 1.8+; Se alguém souber ao certo, atualize aqui.
  6. Se a sua models.pyclasse Meta estiver app_namelistada, renomeie-a também (mencionada por @will).
  7. Se você colocou o nome staticou as templatespastas dentro do aplicativo, também precisará renomeá-las. Por exemplo, renomeie old_app/static/old_apppara new_app/static/new_app.
  8. Para renomear django models, você precisará alterar a django_content_type.nameentrada no DB. Para uso do postgreSQLUPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'

Meta-ponto (se estiver usando virtualenv): Vale a pena notar que, se você estiver renomeando o diretório que contém sua virtualenv, provavelmente haverá vários arquivos em seu ambiente que contêm um caminho absoluto e também precisam ser atualizados. Se você estiver recebendo erros como ImportError: No module named ...esse, pode ser o culpado. (obrigado a @danyamachine por fornecer isso).

Outras referências: você também pode consultar os links abaixo para obter uma imagem mais completa

  1. Renomeando um aplicativo com Django e South
  2. Como faço para migrar um modelo de um aplicativo django para um novo?
  3. Como mudar o nome de um aplicativo Django?
  4. Migração para trás com o Django Sul
  5. A maneira mais fácil de renomear um modelo usando Django / South?
  6. Código Python (graças a A.Raouf ) para automatizar as etapas acima (código não testado. Você foi avisado!)
  7. Código Python (graças a rafaponieman ) para automatizar as etapas acima (código não testado. Você foi avisado!)
Srikar Appalaraju
fonte
3
Além disso, se você tiver modelos, precisará renomear as tabelas de modelos. Para o postgres use ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
null_radix 8/10/12
11
E se você estiver usando as novas migrações, precisará alterar o nome do aplicativo nos arquivos de migração existentes e na tabela django_migrations. Talvez seja melhor reprimir as migrações primeiro, para que haja menos para editar.
James
7
Para o Postgres, se você quiser renomear a sequência também, use ALTER SEQUENCE <oldAppName>_<modelName>_<PK>_seq RENAME TO <newAppName>_<modelName>_<PK>_seq;. Embora não seja necessário, o sistema em si não se importa com o nome. A coluna DEFAULT armazena um OID( 'foo_pkey_seq'::regclass), você pode alterar o nome da sequência sem interromper isso - o OID permanece o mesmo.
Konstantine Kalbazov
3
Seria ótimo se você atualizasse sua resposta para incluir o que James disse sobre a atualização de arquivos de migração (como nomes de módulos de dependência) ... não conseguiu descobrir isso por um tempo.
U3l 30/07/2015
2
Aqui está um comando de gerenciamento que permite renomear o modelo de acordo com a solução do @ SrikarAppalaraju: gist.github.com/rafaponieman/201054ddf725cda1e60be3fe845850a5 Ele aceita old_name, new_name e classes como parâmetros (todos formatados conforme as tabelas e os campos do banco de dados).
Rafaponieman
32

O novo no Django 1.7 é um registro de aplicativo que armazena a configuração e fornece introspecção. Esse mecanismo permite alterar vários atributos do aplicativo.

O ponto principal que quero destacar é que nem sempre é necessário renomear um aplicativo: Com a configuração do aplicativo, é possível resolver aplicativos conflitantes. Mas também o caminho a percorrer se o seu aplicativo precisar de nomes amigáveis.

Como exemplo, desejo nomear meu aplicativo de pesquisas como 'Feedback dos usuários'. É assim:

Crie um apps.pyarquivo no pollsdiretório:

from django.apps import AppConfig

class PollsConfig(AppConfig):
    name = 'polls'
    verbose_name = "Feedback from users"

Adicione a configuração padrão do aplicativo ao seu polls/__init__.py:

default_app_config = 'polls.apps.PollsConfig'

Para mais configurações de aplicativos: https://docs.djangoproject.com/en/1.7/ref/applications/

tudo em maiúsculas
fonte
13

Problema divertido! Vou ter que renomear muitos aplicativos em breve, então fiz uma execução a seco.

Esse método permite avançar em etapas atômicas, para minimizar as interrupções de outros desenvolvedores que trabalham no aplicativo que você está renomeando.

Veja o link na parte inferior desta resposta para obter exemplos de código de trabalho.

  1. Prepare o código existente para a movimentação :
    • Crie uma configuração de aplicativo (defina namee labelpara os padrões).
    • Adicione a configuração do aplicativo a INSTALLED_APPS.
    • Em todos os modelos, defina explicitamente db_tableo valor atual.
    • Migrações de médicos, para que db_table"sempre" sejam definidas explicitamente.
    • Verifique se não são necessárias migrações (verifica a etapa anterior).
  2. Altere o rótulo do aplicativo :

    • Defina labelna configuração do aplicativo como o novo nome do aplicativo.
    • Atualize migrações e chaves estrangeiras para referenciar o novo rótulo do aplicativo.
    • Atualizar modelos para visualizações genéricas baseadas em classe (o caminho padrão é<app_label>/<model_name>_<suffix>.html )
    • Execute o SQL bruto para corrigir migrações e content_typesaplicativos (infelizmente, algum SQL bruto é inevitável). Você não pode executar isso em uma migração.

      UPDATE django_migrations
         SET app = 'catalogue'
       WHERE app = 'shop';
      
      UPDATE django_content_type
         SET app_label = 'catalogue'
       WHERE app_label = 'shop';
    • Verifique se não são necessárias migrações (verifica a etapa anterior).

  3. Renomeie as tabelas :
    • Remova "personalizado" db_table.
    • Execute makemigrationspara que o django possa renomear a tabela "para o padrão".
  4. Mova os arquivos :
    • Renomeie o diretório do módulo.
    • Corrija importações.
    • Atualize as configurações do aplicativo name.
    • Atualize onde faz INSTALLED_APPSreferência à configuração do aplicativo.
  5. Arrumar :
    • Remova a configuração do aplicativo personalizado se não for mais necessário.
    • Se a configuração do aplicativo for removida, não esqueça de removê-lo também INSTALLED_APPS.

Solução de exemplo: eu criei app-rename-example , um projeto de exemplo em que você pode ver como renomeei um aplicativo, um commit por vez.

O exemplo usa Python 2.7 e Django 1.8, mas estou confiante de que o mesmo processo funcionará em pelo menos Python 3.6 e Django 2.1.

reticular
fonte
1
Obrigado @meshy. Realmente me ajudou a renomear um aplicativo enorme. Uma sugestão: após executar a última migração, você poderá excluir todos os arquivos de migração e recriar o arquivo de migração inicial, o que ajudaria se você estivesse realizando um teste de integração contínuo, caso contrário, o IC falhará ao criar o banco de dados de teste.
Rohan
Eu escrevi isso na expectativa de que as migrações fossem executáveis ​​do zero quando o processo foi concluído. Se as migrações falharem, talvez um de nós tenha perdido alguma coisa. Vou pensar sobre isso e ver se há outras etapas que preciso adicionar.
meshy 22/08
@ Rohan, há alguma informação que você possa fornecer para detalhar exatamente como as migrações falharam?
meshy 22/08
Se você executar o teste localmente com os antigos arquivos de migração você pode ver ele vai deixar de criar as tabelas @meshy
Rohan
1
Este plano de jogo funcionou perfeitamente para mim. Desde que cada etapa seja implantada em todos os check-outs ativos (IC, outros desenvolvedores, produção etc.) antes que a próxima etapa seja resolvida, funcionou perfeitamente - sem problemas com as migrações históricas existentes. Execute as etapas em ordem e propague as alterações em qualquer lugar antes de passar para a etapa seguinte.
user85461
11

Caso você esteja usando PyCharm e o projeto pare de funcionar após renomear:

  1. Edite a configuração Executar / Depurar e altere a variável de ambiente DJANGO_SETTINGS_MODULE, pois inclui o nome do seu projeto.
  2. Vá para Configurações / Idiomas e estruturas / Django e atualize o local do arquivo de configurações.
Maziyar Mk
fonte
1
Essa é uma daquelas situações em que encontrar e substituir falhou comigo. Obrigado por apontar isso.
Ruaanvds
0

Migrar novamente a abordagem para uma placa mais limpa.

Isso pode ser feito sem problemas se outros aplicativos não tiverem modelos de chave estrangeira do aplicativo a serem renomeados. Verifique e verifique se os arquivos de migração não listam nenhuma migração desta.

  1. Faça backup do seu banco de dados. Despejar todas as tabelas com a) dados + esquema para possíveis dependências circulares eb) apenas dados para recarregar.
  2. Execute seus testes.
  3. Verifique todo o código no VCS.
  4. Exclua as tabelas de banco de dados do aplicativo a serem renomeadas.
  5. Exclua as permissões: delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>')
  6. Excluir tipos de conteúdo: delete from django_content_type where app_label = '<OldAppName>'
  7. Renomeie a pasta do aplicativo.
  8. Alterar qualquer referência a sua aplicação em suas dependências, ou seja, do aplicativo views.py, urls.py'manage.py', e settings.pyarquivos.
  9. Excluir migrações: delete from django_migrations where app = '<OldAppName>'
  10. Se a sua models.pyclasse Meta estiver app_namelistada, renomeie-a também (mencionada por @will).
  11. Se você colocou o nome staticou as templatespastas dentro do aplicativo, também precisará renomeá-las. Por exemplo, renomeie old_app/static/old_apppara new_app/static/new_app.
  12. Se você definiu a configuração do aplicativo em apps.py; renomeie-os e renomeie suas referências nas configurações.INSTALLED_APPS
  13. Exclua os arquivos de migração.
  14. Refaça as migrações e migre.
  15. Carregue seus dados da tabela de backups.
mehmet
fonte
0

Se você usa o Pycharm , renomear um aplicativo é muito fácil com a refatoração ( Shift+ F6padrão) para todos os arquivos do projeto.
Mas certifique-se de excluir as __pycache__pastas no diretório do projeto e seus subdiretórios. Também tenha cuidado, pois também renomeia os comentários, que você pode excluir na janela de visualização do refatorador, que será exibida.
E você terá que renomear OldNameConfig (AppConfig): além apps.pydo seu aplicativo renomeado.

Se você não deseja perder dados do seu banco de dados, precisará fazê-lo manualmente com a consulta no banco de dados, como a resposta mencionada acima.

Subangkar KrS
fonte
-3

Por que não usar a opção Localizar e substituir? (todo editor de código possui)?

Por exemplo, código do Visual Studio (na opção Editar):

Opção de código do Visual Studio: 'Substituir nos arquivos'

Você apenas digita o nome antigo e o novo nome e substitui tudo no projeto com um clique.

NOTA : Isso renomeia apenas o conteúdo do arquivo, NÃO os nomes dos arquivos e pastas. Não se esqueça de renomear pastas, por exemplo. templates/my_app_name/renomeie-o paratemplates/my_app_new_name/

elano7
fonte