Come cambiare il nome di un'app Django?


156

Ho cambiato il nome di un'app in Django rinominando la sua cartella, le importazioni e tutti i suoi riferimenti (modelli / indici). Ma ora ricevo questo errore quando provo a eseguirepython manage.py runserver

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

Come posso eseguire il debug e risolvere questo errore? Qualche indizio?


Ciao Dani. Sì. Sto anche usando virtualenv, non so se questo abbia qualcosa a che fare con.
André,

1
Se, per caso, stai usando PyCharm, la sua renamefunzionalità ti aiuterà molto in questo.
Anto,

1
Il Sud non sostiene tale operazione?
andilabs

Risposte:


285

Segui questi passaggi per cambiare il nome di un'app in Django:

  1. Rinomina la cartella che si trova nella radice del tuo progetto
  2. Modificare eventuali riferimenti a tua applicazione in loro dipendenze, cioè l'app views.py, urls.py, 'manage.py', e settings.pyfile.
  3. Modifica la tabella del database django_content_typecon il seguente comando:UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
  4. Inoltre, se hai modelli, dovrai rinominare le tabelle dei modelli. Per uso postgres ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName. Anche per mysql penso che sia lo stesso (come menzionato da @null_radix)
  5. (Per Django> = 1.7) Aggiornare il django_migrationstavolo per evitare di avere i tuoi migrazioni precedenti rieseguire: UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'. Nota : c'è qualche dibattito (nei commenti) se questo passaggio è richiesto per Django 1.8+; Se qualcuno lo sa per certo, aggiorna qui.
  6. Se la tua models.pyMeta Class è stata app_nameelencata, assicurati di rinominarla (menzionata da @will).
  7. Se hai inserito spazi per i nomi statico templatescartelle all'interno della tua app, dovrai anche rinominarli. Ad esempio, rinominare old_app/static/old_appin new_app/static/new_app.
  8. Per rinominare django models, dovrai cambiare la django_content_type.namevoce nel DB. Per l'uso postgreSQLUPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'

Meta point (se si utilizza virtualenv): vale la pena notare, se si sta rinominando la directory che contiene virtualenv, probabilmente ci saranno diversi file nel proprio env che contengono un percorso assoluto e dovranno anche essere aggiornati. Se ricevi errori come ImportError: No module named ...questo potrebbe essere il colpevole. (grazie a @danyamachine per averlo fornito).

Altri riferimenti: potresti anche voler fare riferimento ai collegamenti seguenti per un'immagine più completa

  1. Rinominare un'app con Django e Sud
  2. Come faccio a migrare un modello da un'app django a una nuova?
  3. Come cambiare il nome di un'app Django?
  4. Migrazione all'indietro con Django South
  5. Il modo più semplice per rinominare un modello usando Django / South?
  6. Codice Python (grazie ad A.Raouf ) per automatizzare i passaggi precedenti (Codice non testato. Sei stato avvisato!)
  7. Codice Python (grazie a rafaponieman ) per automatizzare i passaggi precedenti (Codice non testato. Sei stato avvisato!)

3
Inoltre, se hai modelli, dovrai rinominare le tabelle dei modelli. Per postgres usare ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
null_radix l'

11
E se stai utilizzando le nuove migrazioni, dovrai cambiare il nome dell'app nei file delle migrazioni esistenti e nella tabella django_migrations. Potrebbe essere meglio prima schiacciare le migrazioni, quindi c'è meno da modificare.
James,

7
Per Postgres, se vuoi rinominare anche la sequenza, usa ALTER SEQUENCE <oldAppName>_<modelName>_<PK>_seq RENAME TO <newAppName>_<modelName>_<PK>_seq;. Sebbene non sia necessario, al sistema stesso non interessa il nome. La colonna DEFAULT memorizza un OID( 'foo_pkey_seq'::regclass), puoi cambiare il nome della sequenza senza interromperlo - l'OID rimane lo stesso.
Konstantine Kalbazov,

3
Sarebbe bello se aggiorni la tua risposta per includere ciò che James ha detto sull'aggiornamento dei file di migrazione (come i nomi dei moduli di dipendenza) ... non riusciresti a capirlo per un bel po '.
u3l

2
Ecco un comando di gestione che consente di rinominare il modello in base alla soluzione di @SrikarAppalaraju : gist.github.com/rafaponieman/201054ddf725cda1e60be3fe845850a5 Accetta old_name, new_name e classi come parametri (tutti formattati come appaiono nelle tabelle e nei campi del database).
rafaponieman,

32

Nuovo in Django 1.7 è un registro delle app che memorizza la configurazione e fornisce introspezione. Questo macchinario ti consente di modificare diversi attributi dell'app.

Il punto principale che voglio sottolineare è che non è sempre necessario rinominare un'app: con la configurazione dell'app è possibile risolvere app in conflitto. Ma anche la strada da percorrere se la tua app necessita di una denominazione amichevole.

Ad esempio, desidero nominare la mia app sondaggi "Feedback dagli utenti". Va così:

Crea un apps.pyfile nella pollsdirectory:

from django.apps import AppConfig

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

Aggiungi la configurazione dell'app predefinita al tuo polls/__init__.py:

default_app_config = 'polls.apps.PollsConfig'

Per ulteriori configurazioni app: https://docs.djangoproject.com/en/1.7/ref/applications/


13

Problema divertente! Presto dovrò rinominare molte app, quindi ho fatto una prova a secco.

Questo metodo consente di compiere progressi nei passaggi atomici, per ridurre al minimo le interruzioni per gli altri sviluppatori che lavorano sull'app che stai rinominando.

Vedi il link in fondo a questa risposta per un esempio di codice funzionante.

  1. Preparare il codice esistente per lo spostamento :
    • Crea una configurazione dell'app (impostata namee labelsui valori predefiniti).
    • Aggiungi la configurazione dell'app a INSTALLED_APPS.
    • Su tutti i modelli, impostare esplicitamente db_tableil valore corrente.
    • Gestire le migrazioni in modo che db_table"sempre" sia stato esplicitamente definito.
    • Assicurarsi che non siano necessarie migrazioni (verifica il passaggio precedente).
  2. Modifica l'etichetta dell'app :

    • Imposta labelnella configurazione dell'app sul nome della nuova app.
    • Aggiorna migrazioni e chiavi esterne per fare riferimento all'etichetta della nuova app.
    • Modelli di aggiornamento per viste generiche basate su classi (il percorso predefinito è<app_label>/<model_name>_<suffix>.html )
    • Esegui SQL raw per correggere migrazioni e content_typesapp (sfortunatamente, è inevitabile che un po 'di SQL raw sia inevitabile). Non è possibile eseguirlo in una migrazione.

      UPDATE django_migrations
         SET app = 'catalogue'
       WHERE app = 'shop';
      
      UPDATE django_content_type
         SET app_label = 'catalogue'
       WHERE app_label = 'shop';
      
    • Assicurarsi che non siano necessarie migrazioni (verifica il passaggio precedente).

  3. Rinomina le tabelle :
    • Rimuovi "personalizzato" db_table.
    • Esegui in makemigrationsmodo che django possa rinominare la tabella "come predefinita".
  4. Sposta i file :
    • Rinomina la directory del modulo.
    • Correggi le importazioni.
    • Aggiorna le configurazioni dell'app name.
    • Aggiorna dove fa INSTALLED_APPSriferimento alla configurazione dell'app.
  5. Riordino :
    • Rimuovi la configurazione dell'app personalizzata se non è più richiesta.
    • Se l'app config è andata, non dimenticare di rimuoverlo anche da INSTALLED_APPS.

Soluzione di esempio: ho creato app-rename-example , un progetto di esempio in cui puoi vedere come ho rinominato un'app, un commit alla volta.

L'esempio usa Python 2.7 e Django 1.8, ma sono sicuro che lo stesso processo funzionerà almeno su Python 3.6 e Django 2.1.


1
Grazie @meshy. Mi ha davvero aiutato a rinominare un'app enorme. Un suggerimento, dopo aver eseguito l'ultima migrazione, è possibile eliminare tutti i file di migrazione e ricreare il file di migrazione iniziale che potrebbe essere d'aiuto se si stanno eseguendo test di integrazione continui, altrimenti l'IC non riuscirà a creare il database di test.
Rohan,

Avevo scritto questo nell'aspettativa che le migrazioni fossero eseguibili da zero una volta terminato il processo. Se le migrazioni sono fallite, forse uno di noi ha perso qualcosa. Ci penserò su e vedrò se ci sono altri passaggi che devo aggiungere.
meshy

@Rohan ci sono delle informazioni che potresti fornire per descrivere in dettaglio come sono fallite le migrazioni?
meshy

Se si esegue il test localmente con i vecchi file di migrazione, si vede che non riuscirà a creare le tabelle @meshy
Rohan

1
Questo piano di gioco ha funzionato perfettamente per me. Finché ogni passaggio viene distribuito attraverso tutti i checkout attivi (CI, altri sviluppatori, produzione, ecc.) Prima che il passaggio successivo venga affrontato, ha funzionato perfettamente, senza problemi con le migrazioni storiche esistenti. Eseguire i passaggi in ordine e propagare le modifiche ovunque prima di passare al passaggio successivo.
user85461

11

Nel caso in cui si utilizzi PyCharm e il progetto smetta di funzionare dopo la ridenominazione:

  1. Modifica la configurazione Esegui / Debug e modifica la variabile d'ambiente DJANGO_SETTINGS_MODULE, poiché include il nome del tuo progetto.
  2. Vai su Impostazioni / Lingue e quadri / Django e aggiorna il percorso del file delle impostazioni.

1
Questa è una di quelle situazioni in cui trovare e sostituire mi ha fallito. Grazie per averlo segnalato.
ruaanvds,

0

Migrare nuovamente l'approccio per un piatto più pulito.

Ciò può essere indolore se altre app non estraggono modelli chiave dall'app da rinominare. Controlla e assicurati che i loro file di migrazione non elencino alcuna migrazione da questo.

  1. Eseguire il backup del database. Scaricare tutte le tabelle con a) dati + schema per possibili dipendenze circolari eb) solo dati per il ricaricamento.
  2. Esegui i tuoi test.
  3. Controlla tutto il codice in VCS.
  4. Elimina le tabelle del database dell'app da rinominare.
  5. Elimina le autorizzazioni: delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>')
  6. Elimina tipi di contenuto: delete from django_content_type where app_label = '<OldAppName>'
  7. Rinomina la cartella dell'app.
  8. Modificare eventuali riferimenti a tua applicazione in loro dipendenze, cioè l'app views.py, urls.py, 'manage.py', e settings.pyfile.
  9. Elimina migrazioni: delete from django_migrations where app = '<OldAppName>'
  10. Se la tua models.pyMeta Class è stata app_nameelencata, assicurati di rinominarla (menzionata da @will).
  11. Se hai inserito spazi per i nomi statico templatescartelle all'interno della tua app, dovrai anche rinominarli. Ad esempio, rinominare old_app/static/old_appin new_app/static/new_app.
  12. Se hai definito la configurazione dell'app in apps.py; rinominare quelli e rinominare i loro riferimenti in settings.INSTALLED_APPS
  13. Elimina i file di migrazione.
  14. Rieseguire le migrazioni e migrare.
  15. Carica i dati della tabella dai backup.

0

Se usi Pycharm , rinominare un'app è molto semplice con il refactoring ( Shift+ F6predefinito) per tutti i file di progetto.
Assicurati di eliminare le __pycache__cartelle nella directory del progetto e nelle sue sottodirectory. Fai anche attenzione perché rinomina anche i commenti che puoi escludere nella finestra di anteprima del refactor che ti mostrerà.
E dovrai rinominare OldNameConfig (AppConfig): apps.pyin aggiunta all'app rinominata.

Se non vuoi perdere i dati del tuo database, dovrai farlo manualmente con query nel database come la risposta di cui sopra.


-3

Perché non usare solo l'opzione Trova e sostituisci. (ce l'ha ogni editor di codice)?

Ad esempio il codice di Visual Studio (sotto l'opzione Modifica):

Opzione codice Visual Studio: "Sostituisci nei file"

Basta digitare il vecchio nome e il nuovo nome e sostituire tutto nel progetto con un clic.

NOTA : questo rinomina solo il contenuto del file, NON i nomi di file e cartelle. Non dimenticare di rinominare le cartelle, ad es. templates/my_app_name/rinominalo intemplates/my_app_new_name/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.