Django ModelChoiceField with custom queryset not validating

My ModelChoiceField is not validating saying that the selected choice is not an instance.

I am passing a custom queryset to my modelChoiceField that uses a custom manager (objects_sys) to return extra entries that are archived and do not normally display with normal queries. The entries are displayed and I can select them, but when the form posts and Django tries to validate, it must be using another query that filters out the archived items so those are not valid choices.

I'm using class based views - this vails in form_valid()

Models:
class Item(models.Model):
    name = UpperCaseCharField(max_length=10, primary_key=True)
    description = models.CharField(max_length=200)

class ItemLoc(models.Model):
    item = models.ForeignKey(Item, on_delete=models.PROTECT)
    location = models.CharField(max_length=200)

My Form:

class ItemForm(forms.ModelForm):
class Meta:
        model = ItemLoc
        fields = (
            'item',
            'location'
            )
    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)

        self.fields['item'].queryset = Items.objects_sys.filter(qty_on_hand__gt=0)

Do I need to pass this custom query in again to the ModelChoiceField at some point so that the extra values are available for validation?

Thank you for your help

class ItemForm(forms.ModelForm):
    class Meta:
        model = ItemLoc
        fields = (
            'item',
            'location'
        )

    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        self.fields['item'].queryset = Item.objects_sys.filter(qty_on_hand__gt=0)

    def clean(self):
        cleaned_data = super().clean()
        item = cleaned_data.get("item")
        if item not in self.fields['item'].queryset:
            raise forms.ValidationError("Invalid item")

This way, in the clean method, you are using the custom queryset that you set up in the init method to check if the selected item is valid.

Back to Top