2012-03-22 10 views
8

Powiedz, że mam tabelę address i ma ona pole postal_code - ModelChoiceField nie pozwala mi używać czegoś innego niż PKs do sprawdzania poprawności istnienia? Jaka byłaby droga? Normalne wejście i użycie clean_*()?Django ModelChoiceField - użyj czegoś innego niż id?

+0

Zależy jak statek relacja jest ustawiony domyślnie ITS z '' postal_code' primary_key' od modelu. Czy możesz podać więcej szczegółów, takich jak twój 'adres' i powiązane modele' postal_code'. Opcja 'ModelChoiceField' domyślnie tworzy listę rozwijaną z opcjami jako istniejącymi instancjami powiązanego modelu. – Pannu

Odpowiedz

0

ModelChoiceFields służą do wybierania między wyborem istniejących instancji modelu. Jest to prawie zawsze najlepiej reprezentowane przez jakąś formę pola Wybierz.

Powiedziałeś, że naprawdę masz adres FK z adresu do kodu pocztowego, jak sugerujesz. Co przechowujesz w tabeli PostalCode, aby uzasadnić dodatkową tabelę, która będzie wymagać połączenia dla każdego zapytania związanego z adresem?

Dla większości przypadków kod pocztowy powinien być po prostu CharField iw takim przypadku, jeśli chcesz sprawdzić, czy wartość jest poprawna, możesz użyć atrybutu choices z listą ważnych kodów pocztowych. Pamiętaj, że ręczne pilnowanie listy ważnych kodów pocztowych to ogromny problem.

Jeśli naprawdę masz tabelę kodów pocztowych i uważasz, że to dobry pomysł (w niektórych przypadkach może to być), możesz rozważyć faktyczne użycie kodu pocztowego jako klucza podstawowego, a nie domyślnego autoinkrementacji, ponieważ jest to Twoje dane są bardziej eksportowalne i rozwiązuje problem z walidacją.

1

Jeśli postal_code jest obcym kluczem do modelu kodu pocztowego, który zawiera ważne kody pocztowe, po prostu skorzystam z funkcji CharField, a następnie wykonaj czysty, jak sugerowałeś. Moja czysta metoda wyglądałaby tak:

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

Co z numerem to_field_name? Nie jestem pewien, czy jest to udokumentowane w dowolnym miejscu, ale można je łatwo znaleźć między ModelChoiceField parami konstruktora: https://github.com/django/django/blob/master/django/forms/models.py. Służy do filtrowania zestawu zapytań pól.

Na przykład:

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

Działa idealnie. – user240515

+2

Uwaga, w wersji 1.4 (nie próbowałem jeszcze 1.5, przepraszam) jest uszkodzony, gdy jest używany z argumentem 'instance', ponieważ' model_to_dict' na siłę używa PK (właściwie 'value_for_object'). Do obejścia trzeba zrobić 'YourForm (..., instance = foo, initial = {" bar ": foo.bar.slug})'. Zobacz szczegóły implementacji 'BaseModelForm .__ init__'. – drdaeman

+1

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

Powiązane problemy