2011-01-14 3 views
13

Ho una funzione di terze parti che mi fornisce un set di filtri filtrato (ad es. Record con 'valid' = True) ma voglio rimuovere una particolare condizione (es. Per avere tutti i record, entrambi validi e non validi).Django: rimuove una condizione di filtro da un setaccio

C'è un modo per rimuovere una condizione di filtro in un queryset già filtrato?

E.g.

only_valid = MyModel.objects.filter(valid=True) 
all_records = only_valid.**remove_filter**('valid') 

(so che sarebbe meglio definire 'all_records' prima 'only_valid', ma questo è solo un esempio ...)

+0

si può mostrare l'esempio di codice, per favore? –

risposta

4

Da the docs:

Ogni volta si raffina un QuerySet, si ottiene un nuovissimo QuerySet che non è in alcun modo associato al QuerySet precedente. Ogni perfezionamento crea un QuerySet separato e distinto che può essere archiviato, utilizzato e riutilizzato.

Dubito quindi che esista un modo standard per farlo. È possibile dig into the code, vedere, cosa fa filter() e provare un po '. Se questo non aiuta, la mia ipotesi è che sei sfortunato e hai bisogno di ricostruire la query da solo.

10

Anche se non esiste un modo ufficiale per farlo utilizzando la notazione del filtro, è possibile farlo facilmente con Q -notazione. Per esempio, se ci si assicura che la funzione di terza parte restituisce un oggetto Q, non un QuerySet filtrato, si possono effettuare le seguenti operazioni:

q = ThirdParty() 
q = q | Q(valid=False) 

E le condizioni SQL risultante sarà affiancato con operatore OR.

+0

Avrai bisogno di accedere al codice di terze parti, ma sì, questa è una buona soluzione. +1 – Boldewyn

1

Ecco cosa ho fatto in un caso simile.

all_records = MyModel.objects.all() 
only_valid = MyModel.objects.filter(valid=True) 
only_valid.original = all_records 

... 

all_records = only_valid.original 

Ovviamente questo cancella anche altri filtri, quindi non sarà corretto per tutti i casi.

0

Grazie per avermi fatto controllare il codice sorgente Boldewyn. Così, sembra che ci sia un nuovo metodo giusto al di sotto del filtro() con gli stessi parametri ... chiamato exclude() (come di commettere mini-hash ef6c680, per quando perde la sua numero di riga)

restituire una nuova istanza QuerySet con NOT (args) ANDed al set esistente.

Quindi, per rispondere alla domanda iniziale:

only_valid = MyModel.objects.filter(valid=True) 
filtered_results = only_valid.exclude(the_condition_to_remove=True) 
+0

'exclude' aggiunge semplicemente un altro filtro, mantenendo quelli esistenti. Non ripristina il queryset completo. – Don

+0

Oh, capisco! Ho quindi frainteso la domanda. Grazie per averlo chiarito :) – iddy