Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

54
Visualizações
Django ChoiceField, ModelChoiceField validation

I see that forms.ChoiceField is using this code to validate the value:

def validate(self, value):
    """
    Validates that the input is in self.choices.
    """
    super(ChoiceField, self).validate(value)
    if value and not self.valid_value(value):
        raise ValidationError(
            self.error_messages['invalid_choice'],
            code='invalid_choice',
            params={'value': value},
        )

def valid_value(self, value):
    "Check to see if the provided value is a valid choice"
    text_value = force_text(value)
    for k, v in self.choices:
        if isinstance(v, (list, tuple)):
            # This is an optgroup, so look inside the group for options
            for k2, v2 in v:
                if value == k2 or text_value == force_text(k2):
                    return True
        else:
            if value == k or text_value == force_text(k):
                return True
    return False

and forms.models.ModelChoiceField this code:

def validate(self, value):
    return Field.validate(self, value)

Q1. Why Django uses validation to check if the selected value (from dropdown) is indeed in the choice list for forms.ChoiceField?

Q2. When Django uses the validation from Q1, to check if the value is indeed in the choice list, why does not also check if the selected value is in the model records for forms.models.ModelChoiceField?

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The validation process starts from form.full_clean() where you have form._clean_fields() and form._clean_form executed in this order.

Now if you take a closer look at what form._clean_fields() do, you will probably notice that it only calls field.clean(value, initial) and collects the results into a cleaned_data dict. So the interesting part is at field.clean, lets see what happens there:

def clean(self, value):
    """
    Validate the given value and return its "cleaned" value as an
    appropriate Python object. Raise ValidationError for any errors.
    """
    value = self.to_python(value)
    self.validate(value)
    self.run_validators(value)
    return value

First, we have a to_python call, followed by validate and finishing with run_validators.

So in terms of ModelChoiceField when you reach the .validate method, your choice is already a Model instance, thats why, this kind of validation (from Q2) is happening inside the to_python method.

def to_python(self, value):
    if value in self.empty_values:
        return None
    try:
        key = self.to_field_name or 'pk'
        value = self.queryset.get(**{key: value})
    except (ValueError, TypeError, self.queryset.model.DoesNotExist):
        raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
    return value
about 4 years ago · Santiago Trujillo Relatório

0

one thing i can say is for forms.ChoiceField the input are coming from the user perspective means a user can use inspect element and enter a choice which doesnt appear from the backend .

but for models one the choices are directly coming from the backend or the database

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda