2012-03-22 14 views
8

Dire che ho una tabella address e ha un campo postal_code - ModelChoiceField non mi consente di utilizzare qualcosa di diverso dai PK per convalidare l'esistenza corretta? Quale sarebbe la strada da percorrere? Ingresso normale e uso clean_*()?Django ModelChoiceField - usa qualcosa di diverso dall'ID?

+0

dipende da come la nave relazione è impostato, per default il suo con il '' primary_key' del modello postal_code'. Puoi fornire maggiori dettagli come il tuo 'indirizzo' e i relativi modelli' postal_code'. Un 'ModelChoiceField' per impostazione predefinita crea un menu a discesa con opzioni come istanze esistenti del modello correlato. – Pannu

risposta

0

ModelChoiceFields devono essere utilizzati per selezionare tra una scelta di istanze di modello esistenti. Questo è quasi sempre meglio rappresentato da una qualche forma di campo Seleziona.

Detto questo, hai davvero un FK dall'indirizzo a CAP che stai insinuando. Cosa stai memorizzando su una tabella PostalCode per giustificare la tabella aggiuntiva che dovrà essere aggiunta per ogni query relativa all'indirizzo?

Per la maggior parte dei casi, il codice postale deve essere semplicemente un CharField e in tal caso, se si desidera verificare che il valore sia valido, è possibile utilizzare l'attributo choices con un elenco di codici postali validi. Tieni presente che mantenere una lista di codici postali validi a mano è una seccatura enorme.

Se hai davvero una tabella PostalCode e pensi che sia una buona idea (che in alcuni casi potrebbe essere) potresti prendere in considerazione l'utilizzo del codice postale come chiave primaria piuttosto che l'autoincremento predefinito poiché è necessariamente univoco, rende i tuoi dati sono più esportabili e risolvono il problema con la convalida.

1

Se postal_code è una chiave esterna a un modello di PostalCode che contiene codici postali validi, vorrei utilizzare solo un CharField e quindi effettuare una pulizia come suggerito. Il mio metodo clean sarebbe il seguente:

def clean_postal_code(self): 
    try: 
     code = PostalCode.objects.get(code_field=self.data['postal_code']) 
    except: 
     raise forms.ValidationError("Please enter a valid postal code") 
    return code 
20

Che dire di to_field_name? Non sono sicuro che sia documentato ovunque, ma lo puoi trovare facilmente tra i parametri del costruttore ModelChoiceField: https://github.com/django/django/blob/master/django/forms/models.py. È usato per filtrare il campo queryset.

Ad esempio:

articles = ModelChoiceField(queryset=Articles.objects.all(), 
     to_field_name='slug') 
+0

Funziona perfettamente. – user240515

+2

Attenzione, in 1.4 (non ho ancora provato 1.5, scusa) è rotto quando usato con l'argomento 'instance', dato che' model_to_dict' usa forzatamente PK (in realtà, 'valore_per_oggetto '). Per ovviare a ciò si deve fare 'YourForm (..., instance = foo, initial = {" bar ": foo.bar.slug})'. Vedi l'implementazione di 'BaseModelForm .__ init__' per i dettagli. – drdaeman

+1

@drdaeman [Indeed] (https://code.djangoproject.com/ticket/20202) – valtron

Problemi correlati