Search code examples
djangodjango-2.1

Remove the selected option from the choice field in admin panel


I want to reduce the choice option in the admin panel if it is selected once.

admin.py

class MyModelForm(forms.ModelForm):
    LOC = [('op1', 'op1'), ('op2', 'op2'),...]

    location = forms.ChoiceField(choices=LOC)


class DataModelAdmin(admin.ModelAdmin):
    form = MyModelForm
    list_display = ('location',)
    search_fields = ['location']

    def get_ordering(self, request):
        return ['location']


admin.site.register(DataModel, DataModelAdmin)

model.py

class DataModel(models.Model):
    location = models.CharField(max_length=50, unique=True)

    def __str__(self):
        return self.location

I am trying to do but it removes the selected option on restarting the server


Solution

  • If I'm interpreting your question correctly you want to remove the object's location from the field choices...

    class MyModelForm(forms.ModelForm):
        LOC = [('op1', 'op1'), ('op2', 'op2')]
    
        location = forms.ChoiceField()
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            if self.instance:
                self.fields['location'].choices = [
                    choice for choice in self.LOC
                    if choice[0] != self.instance.location
                ]
            else:
                self.fields['location'].choices = self.LOC
    

    Actually on second read maybe you're looking for a filter?

    from django.contrib.admin import SimpleListFilter
    
    class LocationFilter(SimpleListFilter):
        title = 'location'
        parameter_name = 'location'
    
        def lookups(self, request, model_admin):
            locations = DataModel.objects.values_list('location', flat=True)
            return locations
    
        def queryset(self, request, queryset):
            if self.value():
                return queryset.filter(location=self.value())
    

    Then add list_filter = (LocationFilter,) to your admin class.