Home > OS >  Django ForeignKey, hide from user select options in dropdown menu
Django ForeignKey, hide from user select options in dropdown menu

Time:12-02

I have standard Django models with ForeignKey.

Django docs:

"ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet."

and

"If the model field has choices set, then the form field’s widget will be set to Select, with choices coming from the model field’s choices."

Now I have dropdown menu with choices.

I don't want dropdown menu where user can see options. I want CharField(textfield or similar) where user type, but still that must be one of the options from the database for that field. He must type a valid entry.

I tried:

class TransakcijeForm(forms.ModelForm):
    model = models.Transakcije
    fields = .....
    labels = .....
    widgets ={'subscriber':forms.TextInput()}

but I receive the message:

"Select a valid choice. That choice is not one of the available choices." (entry is correct and it works with dropdown menu)

This is my first question here and I'm sorry if I miss the form.

CodePudding user response:

The reason you are getting that error is because your form is still treating the subscriber field as a ModelChoiceField because you are only overriding what widget is rendered to html. You need to change the actual field type of your field. You can define your form like this:

from django.core.exceptions import ValidationError

class TransakcijeForm(forms.ModelForm):
   subscriber = forms.CharField()
   class Meta:
      model = models.Transakcije
      fields = ....
      labels = ....
   
   def clean_subscriber(self):
      subscriber_id = self.cleaned_data['subscriber']
      try:
         # adjust this line to appropriately get the model object that you need
         subscriber = SubscriberModel.objects.get(id=subscriber_id)
         return subscriber
      except:
         raise ValidationError('Subscriber does not exist')

The line subscriber = forms.CharField() will change the form to treat the field as a CharField rather than a ModelChoiceField. Doing this will cause the form to return the subscriber field value as a string, so you will need to get the appropriate model object based on the value of the field. That is what the clean_subscriber(self) function is for. It needs to be named like clean_<field name>(). That function will take the string that is returned by the form, try and find the correct model object and return it if an object is found. If it finds no matching objects it will raise a ValidationError so the form doesn't submit with a bad value.

  • Related