2016-07-11 15 views
0

Ich schreibe ein Suchformular für ein Django-Modell, das die Spalte is_ok als NullBooleanField enthält.Suchformular für NullBooleanField

Ich möchte 4 Möglichkeiten haben:

  • Suche nach Fällen, in denen diese Spalte wahr ist.
  • Suche nach Instanzen, in denen diese Spalte falsch ist.
  • Suche nach Instanzen, in denen diese Spalte NULL ist.
  • ignorieren Sie diese Spalte in der Suche

Bis ich diese verwenden jetzt:

is_ok = forms.NullBooleanField(required=False) 

Aber das macht nur drei Optionen (Dropdown-Liste).

Wie wird hier zwischen "is NULL" und "nicht gesetzt" unterschieden?

+0

Ich glaube nicht, dass eine Art und Weise gibt es zwischen den beiden zu unterscheiden - ich denke, Sie 'Unterklasse müssen die NullBooleanSelect' Widget und 'NullBooleanField'. – Alasdair

+0

Was ist der Unterschied zwischen den beiden? – e4c5

+0

@ e4c5 gibt es vier Möglichkeiten zu suchen. Stellen Sie sich vor, die Tabelle hat drei Zeilen. Eine Zeile mit ok = true, eine mit ok = false, eine mit ok = NULL. Die vierte Art zu suchen ist: Ignoriere diese Spalte. Hast du das verstanden? Wenn nicht bitte, frage nochmal. – guettli

Antwort

1

Wie @Alasdair sagte, werden Sie ein benutzerdefiniertes Feld erstellen müssen:

class UnsetType: 
    def __str__(self): 
     return '__unset__' 

Unset = UnsetType() 

class UnsetOrNullBooleanSelect(NullBooleanSelect): 
    def __init__(self, attrs=None): 
     choices = (
      ('__unset__', ugettext_lazy('Unset')), 
      ('1', ugettext_lazy('Unknown')), 
      ('2', ugettext_lazy('Yes')), 
      ('3', ugettext_lazy('No')), 
     ) 
     super().__init__(attrs, choices) 

    def render(self, name, value, attrs=None): 
     try: 
      value = { 
       True: '2', False: '3', None: '1', 
       '2': '2', '3': '3', '1': '1', 
      }[value] 
     except KeyError: 
      value = '__unset__' 
     return super().render(name, value, attrs) 

    def value_from_datadict(self, data, files, name): 
     value = data.get(name) 
     return { 
      '1': None, None: None, 'None': None, 'none': None, 'null': None, 
      '2': True, True: True, 'True': True, 
      '3': False, 'False': False, False: False, 
     }.get(value, Unset) 

class UnsetOrNullBooleanField(NullBooleanField): 

    widget = UnsetOrNullBooleanSelect 

    def to_python(self, value): 
     if value in (True, 'True', 'true', '1'): 
      return True 
     elif value in (False, 'False', 'false', '0'): 
      return False 
     elif value in (None, 'None', 'none', 'null'): 
      return None 
     else: 
      return Unset 
+0

vielen Dank. Nachdem ich nochmal darüber nachgedacht habe, erinnere ich mich an eine db-Faustregel: Vermeiden Sie nullable db-Spalten. Siehe den "Abschluss" -Teil meiner Frage. Trotzdem, vielen Dank. Du bekommst das Kopfgeld! – guettli

+0

Ich habe jetzt nicht über diese "Vermeiden Sie Nullable DB Spalten" -Anweisung. Aber ich stimme dem nicht wirklich zu. Siehe diese Frage: http://dba.stackexchange.com/questions/5222/why-shouldnt-we-allow-nulls –