2015-10-15 8 views
5

Ho un modello con scelte dinamiche e vorrei restituire una lista di scelta vuota se posso garantire che il codice venga eseguito in caso di un Comando django-admin.py migrate/makemigrations per impedire la creazione o l'avviso di modifiche di scelta inutili.Rileva se il codice viene eseguito nel contesto del comando migrate/makemigrations

Codice:

from artist.models import Performance 
from location.models import Location 

def lazy_discover_foreign_id_choices(): 
    choices = [] 

    performances = Performance.objects.all() 
    choices += {performance.id: str(performance) for performance in performances}.items() 

    locations = Location.objects.all() 
    choices += {location.id: str(location) for location in locations}.items() 

    return choices 
lazy_discover_foreign_id_choices = lazy(lazy_discover_foreign_id_choices, list) 


class DiscoverEntry(Model): 
    foreign_id = models.PositiveIntegerField('Foreign Reference', choices=lazy_discover_foreign_id_choices(),) 

Così mi potrebbe pensare se riesco a rilevare il contesto di esecuzione in lazy_discover_foreign_id_choices quindi posso scegliere di uscita una lista scelta vuota. Stavo pensando di provare sys.argv e __main__.__name__ ma spero ci sia un modo più affidabile o un'API?

+1

In che modo le tue scelte sono dinamiche? Potresti postare del codice? – aumo

+0

Sicuro, codice aggiunto – DanH

+0

Come importate 'Performance' e' Location'? – Ivan

risposta

2

Una soluzione che posso pensare sarebbe quella di sottoclasse il comando Django makemigrations per impostare un flag prima di eseguire effettivamente l'operazione effettiva.

Esempio:

Metti che il codice in <someapp>/management/commands/makemigrations.py, avrà la precedenza comando predefinito makemigrations di Django.

from django.core.management.commands import makemigrations 
from django.db import migrations 


class Command(makemigrations.Command): 
    def handle(self, *args, **kwargs): 
     # Set the flag. 
     migrations.MIGRATION_OPERATION_IN_PROGRESS = True 

     # Execute the normal behaviour. 
     super(Command, self).handle(*args, **kwargs) 

Fare lo stesso per il comando migrate.

e modificare le dinamiche funzione di scelte:

from django.db import migrations 


def lazy_discover_foreign_id_choices(): 
    if getattr(migrations, 'MIGRATION_OPERATION_IN_PROGRESS', False): 
     return [] 
    # Leave the rest as is. 

E 'molto hacky ma abbastanza facile da installare.

+0

Grazie per il suggerimento, ma questo non funziona. Sembra che le scelte del campo modello siano eseguite prima di 'Command.handle()' – DanH

+0

L'ho provato su un mio progetto e sembrava funzionare, indagherò. – aumo

+0

@DanH Confermo che funziona bene su una installazione pulita di Django 1.8.5, sei sicuro che sia il nuovo comando che viene eseguito e non quello predefinito? – aumo

4

Ecco un modo hacky abbastanza non per fare questo (dal django crea già le bandiere per noi):

import sys 
def lazy_discover_foreign_id_choices(): 
    if ('makemigrations' in sys.argv or 'migrate' in sys.argv): 
     return [] 
    # Leave the rest as is. 

Questo dovrebbe funzionare per tutti i casi.

+0

Oh, questo è davvero un bel modo per farlo. –

Problemi correlati