4

I have a regular self-referential foreign key:

idol = models.ForeignKey("self", on_delete=models.CASADE)

The admin page allows me to choose the the same object id. How can I prevent the django admin form from showing it?

iTayb
  • 12,373
  • 24
  • 81
  • 135

3 Answers3

6

You can override formfield_for_foreignkey in your subclass of ModelAdmin class.

The formfield_for_foreignkey method on a ModelAdmin allows you to override the default formfield for a foreign keys field.

Parent object id can be saved in change_view method:

class IdolAdmin(admin.ModelAdmin):
    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.object_id = object_id
        return super(IdolAdmin, self).change_view(
            request, object_id, form_url, extra_context=extra_context,
        )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "idol":
            kwargs['queryset'] = Idol.objects.exclude(pk=self.object_id)
        return super(IdolAdmin, self).formfield_for_foreignkey(
            db_field, request, **kwargs)
ndpu
  • 22,225
  • 6
  • 54
  • 69
4

You should be able set the form for your model admin to a custom form that contains the modification

class ModelAdmin...
    form = MyModelForm

I'd imagine the form would look something like this

class MyModelForm(ModelForm)
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)
        if self.instance.pk:
            query = self.fields['my_field'].queryset 
            self.fields['my_field'].queryset = query.exclude(id=self.instance.id)
Sayse
  • 42,633
  • 14
  • 77
  • 146
0

You can extend render_change_form .

class IdolAdmin(admin.ModelAdmin):
    def render_change_form(self, request, context, *args, **kwargs):
         queryset = context['adminform'].form.fields['idol'].queryset
         original_id = context.get('original', None)
         if(original_id):
             context['adminform'].form.fields['idol'].queryset = queryset.exclude(id=original_id.id)
         return super(IdolAdmin, self).render_change_form(request, context, args, kwargs)         
Prashant Gaur
  • 9,540
  • 10
  • 49
  • 71