Jak zmienić nazwę aplikacji Django?

156

Zmieniłem nazwę aplikacji w Django, zmieniając nazwę jej folderu, importu i wszystkich jej odniesień (szablonów / indeksów). Ale teraz pojawia się ten błąd, kiedy próbuję uruchomićpython manage.py runserver

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

Jak mogę debugować i rozwiązać ten błąd? Jakieś wskazówki?

André
źródło
Cześć danihp. Tak, mam. Używam również virtualenv, nie wiem, czy to ma coś wspólnego.
André
1
Jeśli przypadkiem używasz PyCharm, jego renamefunkcja bardzo ci w tym pomoże.
Anto,
1
Czy Południe nie wspiera takiej operacji?
andilabs

Odpowiedzi:

285

Wykonaj następujące kroki, aby zmienić nazwę aplikacji w Django:

  1. Zmień nazwę folderu, który znajduje się w katalogu głównym projektu
  2. Zmień żadnych odniesień do aplikacji w ich zależności, czyli aplikacji views.py, urls.py, „” manage.py i settings.pyplików.
  3. Edytuj tabelę bazy danych django_content_typeza pomocą następującego polecenia:UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
  4. Również jeśli masz modele, będziesz musiał zmienić nazwy tabel modeli. Do użytku postgres ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName. Dla mysql też myślę, że to to samo (o czym wspomniał @null_radix)
  5. (Dla Django> = 1.7) Aktualizacja django_migrationstabeli, aby uniknąć konieczności Twoje poprzednie migracje ponownie uruchomić: UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'. Uwaga : istnieje pewna dyskusja (w komentarzach), czy ten krok jest wymagany dla Django 1.8+; Jeśli ktoś wie na pewno, zaktualizuj tutaj.
  6. Jeśli Twoja models.pymeta klasa została app_namewymieniona, pamiętaj, aby zmienić jej nazwę (wspomnianą przez @will).
  7. Jeśli masz przestrzeń nazw folderów staticlub templatesw aplikacji, musisz również zmienić ich nazwy. Na przykład zmień nazwę old_app/static/old_appna new_app/static/new_app.
  8. Aby zmienić nazwę django models, musisz zmienić django_content_type.namewpis w DB. Do użytku z PostgreSQLUPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'

Meta punkt (jeśli używasz virtualenv): Warto zauważyć, że jeśli zmieniasz nazwę katalogu zawierającego virtualenv, prawdopodobnie w twoim pliku env będzie kilka plików, które zawierają bezwzględną ścieżkę i również będą wymagały aktualizacji. Jeśli otrzymujesz błędy, takie jak ImportError: No module named ...ten, może to być przyczyną. (dzięki @danyamachine za zapewnienie tego).

Inne odniesienia: możesz również odnieść się do poniższych linków, aby uzyskać pełniejszy obraz

  1. Zmiana nazwy aplikacji na Django i South
  2. Jak migrować model z jednej aplikacji django do nowej?
  3. Jak zmienić nazwę aplikacji Django?
  4. Migracja wsteczna z Django South
  5. Najłatwiejszy sposób na zmianę nazwy modelu przy użyciu Django / South?
  6. Kod w Pythonie (podziękowania dla A.Raouf ) w celu zautomatyzowania powyższych kroków (kod nieprzetestowany. Ostrzegamy Cię!)
  7. Kod Pythona (dzięki rafaponieman ) w celu zautomatyzowania powyższych kroków (kod nieprzetestowany. Zostałeś ostrzeżony!)
Srikar Appalaraju
źródło
3
Również jeśli masz modele, będziesz musiał zmienić nazwy tabel modeli. Do użytku postgres ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
null_radix
11
A jeśli używasz nowych migracji, musisz zmienić nazwę aplikacji w istniejących plikach migracji i tabeli django_migrations. Lepiej byłoby najpierw ograniczyć migracje, aby było mniej do edycji.
James
7
W przypadku Postgres, jeśli chcesz również zmienić nazwę sekwencji, użyj ALTER SEQUENCE <oldAppName>_<modelName>_<PK>_seq RENAME TO <newAppName>_<modelName>_<PK>_seq;. Chociaż nie jest to konieczne, sam system nie dba o nazwę. Kolumna DEFAULT przechowuje OID( 'foo_pkey_seq'::regclass), możesz zmienić nazwę sekwencji bez przerywania jej - OID pozostaje taki sam.
Konstantine Kalbazov
3
Byłoby wspaniale, gdybyś zaktualizował swoją odpowiedź, aby zawierała to, co powiedział James o uaktualnianiu plików migracyjnych (takich jak nazwy modułów zależności) ... przez długi czas nie mogłeś tego zrozumieć.
u3l
2
Oto polecenie zarządzania, które pozwala na zmianę nazwy modelu zgodnie z rozwiązaniem @ SrikarAppalaraju: gist.github.com/rafaponieman/201054ddf725cda1e60be3fe845850a5 Przyjmuje jako parametry stara_nazwa, nowa_nazwa i klasy (wszystkie sformatowane, gdy wyglądają na tabelach i polach bazy danych).
rafaponieman
32

Nowością w Django 1.7 jest rejestr aplikacji, który przechowuje konfigurację i zapewnia introspekcję. Ta maszyna umożliwia zmianę kilku atrybutów aplikacji.

Główną kwestią, którą chcę podkreślić, jest to, że zmiana nazwy aplikacji nie zawsze jest konieczna: dzięki konfiguracji aplikacji można rozwiązać konfliktowe aplikacje. Ale także do zrobienia, jeśli Twoja aplikacja wymaga przyjaznego nazewnictwa.

Jako przykład chcę nazwać moją aplikację ankietową „Opinie użytkowników”. To wygląda tak:

Utwórz apps.pyplik w pollskatalogu:

from django.apps import AppConfig

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

Dodaj domyślną konfigurację aplikacji do polls/__init__.py:

default_app_config = 'polls.apps.PollsConfig'

Więcej konfiguracji aplikacji: https://docs.djangoproject.com/en/1.7/ref/applications/

wszystkie duże litery
źródło
13

Zabawny problem! Wkrótce będę musiał zmienić nazwy wielu aplikacji, więc wykonałem próbę.

Ta metoda umożliwia dokonywanie postępów w atomowych krokach, aby zminimalizować zakłócenia dla innych programistów pracujących nad aplikacją, której nazwę zmieniasz.

Zobacz link na dole tej odpowiedzi, aby uzyskać działający przykładowy kod.

  1. Przygotuj istniejący kod do przeniesienia :
    • Utwórz konfigurację aplikacji (ustaw namei labelna domyślne).
    • Dodaj konfigurację aplikacji do INSTALLED_APPS.
    • We wszystkich modelach jawnie ustawione db_tablena bieżącą wartość.
    • Migracje lekarzy, które db_tablebyły „zawsze” wyraźnie zdefiniowane.
    • Upewnij się, że migracje nie są wymagane (sprawdź poprzedni krok).
  2. Zmień etykietę aplikacji :

    • Ustaw labelw konfiguracji aplikacji na nową nazwę aplikacji.
    • Zaktualizuj migracje i klucze obce, aby odnosiły się do nowej etykiety aplikacji.
    • Aktualizuj szablony dla ogólnych widoków opartych na klasach ( domyślna ścieżka to<app_label>/<model_name>_<suffix>.html )
    • Uruchom surowy SQL, aby naprawić migracje i content_typesaplikację (niestety, niektóre surowe SQL są nieuniknione). Nie możesz tego uruchomić podczas migracji.

      UPDATE django_migrations
         SET app = 'catalogue'
       WHERE app = 'shop';
      
      UPDATE django_content_type
         SET app_label = 'catalogue'
       WHERE app_label = 'shop';
      
    • Upewnij się, że migracje nie są wymagane (sprawdź poprzedni krok).

  3. Zmień nazwy tabel :
    • Usuń „niestandardowy” db_table.
    • Uruchom, makemigrationsaby django mogło zmienić nazwę tabeli na „domyślną”.
  4. Przenieś pliki :
    • Zmień nazwę katalogu modułu.
    • Napraw import.
    • Zaktualizuj konfigurację aplikacji name.
    • Zaktualizuj, gdzie INSTALLED_APPSodwołuje się do konfiguracji aplikacji.
  5. Porządkuj :
    • Usuń niestandardową konfigurację aplikacji, jeśli nie jest już wymagana.
    • Jeśli konfiguracja aplikacji zniknęła, nie zapomnij usunąć jej również z INSTALLED_APPS.

Przykładowe rozwiązanie: stworzyłem app-rename-example , przykładowy projekt, w którym możesz zobaczyć, jak zmieniłem nazwę aplikacji, po jednym zatwierdzeniu na raz.

W przykładzie użyto Pythona 2.7 i Django 1.8, ale jestem pewien, że ten sam proces będzie działał przynajmniej na Pythonie 3.6 i Django 2.1.

siatkowaty
źródło
1
Dzięki @meshy. Naprawdę pomogło mi to zmienić nazwę ogromnej aplikacji. Jedna sugestia: po przeprowadzeniu ostatniej migracji można usunąć wszystkie pliki migracji i odtworzyć początkowy plik migracji, co byłoby pomocne w przypadku ciągłych testów integracji, w przeciwnym razie CI nie utworzy testowej bazy danych.
Rohan
Napisałem to, spodziewając się, że migracje będą możliwe do uruchomienia od zera po zakończeniu procesu. Jeśli migracje się nie powiodły, być może ktoś z nas coś przeoczył. Przemyślę to i zobaczę, czy muszę dodać jakieś inne kroki.
meshy
@Rohan czy są jakieś informacje, które mógłbyś podać, aby szczegółowo opisać, dlaczego migracje się nie powiodły?
meshy
Jeśli uruchomisz test lokalnie ze starymi plikami migracji, zobaczysz, że nie uda się utworzyć tabel @meshy
Rohan
1
Ten plan gry działał dla mnie idealnie. Tak długo, jak każdy krok jest wdrażany przez wszystkie aktywne kasy (CI, inni deweloperzy, produkcja itp.) Przed przejściem do następnego kroku, działał idealnie - bez problemów z istniejącymi migracjami historycznymi. Wykonaj kroki po kolei i rozpowszechnij zmiany wszędzie, zanim przejdziesz do następnego kroku.
user85461
11

Jeśli używasz PyCharm i projekt przestaje działać po zmianie nazwy:

  1. Edytuj konfigurację Run / Debug i zmień zmienną środowiskową DJANGO_SETTINGS_MODULE, ponieważ zawiera ona nazwę twojego projektu.
  2. Przejdź do Settings / Languages ​​& Frameworks / Django i zaktualizuj lokalizację pliku ustawień.
Maziyar Mk
źródło
1
To jedna z tych sytuacji, w których znajdowanie i zastępowanie zawiodło. Dziękuję za zwrócenie uwagi.
ruaanvds
0

Podejście ponownej migracji w celu uzyskania czystszej płytki.

Można to zrobić bezboleśnie, JEŚLI inne aplikacje nie mają modeli kluczy obcych z aplikacji, której nazwa ma zostać zmieniona. Sprawdź i upewnij się, że ich pliki migracji nie zawierają żadnych migracji z tego.

  1. Utwórz kopię zapasową bazy danych. Zrzuć wszystkie tabele z a) danymi + schematem dla możliwych zależności cyklicznych i b) tylko danymi do ponownego załadowania.
  2. Przeprowadź testy.
  3. Sprawdź cały kod w VCS.
  4. Usuń tabele bazy danych aplikacji, której nazwa ma zostać zmieniona.
  5. Usuń uprawnienia: delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>')
  6. Usuń typy zawartości: delete from django_content_type where app_label = '<OldAppName>'
  7. Zmień nazwę folderu aplikacji.
  8. Zmień żadnych odniesień do aplikacji w ich zależności, czyli aplikacji views.py, urls.py, „” manage.py i settings.pyplików.
  9. Usuń migracje: delete from django_migrations where app = '<OldAppName>'
  10. Jeśli Twoja models.pymeta klasa została app_namewymieniona, pamiętaj, aby zmienić jej nazwę (wspomnianą przez @will).
  11. Jeśli masz przestrzeń nazw folderów staticlub templatesw aplikacji, musisz również zmienić ich nazwy. Na przykład zmień nazwę old_app/static/old_appna new_app/static/new_app.
  12. Jeśli zdefiniowałeś konfigurację aplikacji w apps.py; zmień ich nazwy i zmień nazwy ich odniesień w settings.INSTALLED_APPS
  13. Usuń pliki migracji.
  14. Ponownie wykonaj migracje i przeprowadź migrację.
  15. Załaduj dane tabeli z kopii zapasowych.
mehmet
źródło
0

Jeśli używasz Pycharm , zmiana nazwy aplikacji jest bardzo łatwa dzięki refaktoryzacji ( Shift+ F6domyślnej) dla wszystkich plików projektu.
Ale pamiętaj, aby usunąć __pycache__foldery w katalogu projektu i jego podkatalogach. Uważaj również, ponieważ zmienia również nazwy komentarzy, które możesz wykluczyć w oknie podglądu refaktora, które pokaże.
Ponadto będziesz musiał zmienić nazwę OldNameConfig (AppConfig): in apps.pyswojej aplikacji o zmienionej nazwie.

Jeśli nie chcesz stracić danych swojej bazy danych, będziesz musiał to zrobić ręcznie za pomocą zapytania w bazie danych, takiego jak wyżej wymieniona odpowiedź.

Subangkar KrS
źródło
-3

Dlaczego nie skorzystać po prostu z opcji Znajdź i zamień. (każdy edytor kodu to ma)?

Na przykład Visual Studio Code (w opcji Edycja):

Opcja Visual Studio Code: „Zamień w plikach”

Po prostu wpisujesz starą i nową nazwę i zamieniasz wszystko w projekcie jednym kliknięciem.

UWAGA : Spowoduje to zmianę nazwy tylko zawartości pliku, a NIE nazw plików i folderów. Nie zapomnij o zmianie nazw folderów, np. templates/my_app_name/zmień jego nazwę natemplates/my_app_new_name/

elano7
źródło