4

I have a Person model, which has a ForeignKey field to itself, called mother. When the user goes to the 'add' admin form, I want to define an initial value for mother, in case there is a GET('mother') parameter, or leave it blank, in case there is not.

I have actually 2 questions:

  1. How to access request inside ModelAdmin?
  2. How to define initial value for a ForeignKey field?

In models.py:

class Person(models.Model):
    name=models.CharField()
    mother=models.ForeignKey('self')

In admin.py:

class  PersonAdminForm(forms.ModelForm):
    class Meta:
        model = Person

class PersonAdmin(admin.ModelAdmin):
    mother = request.GET.get('mother','') #don`t know how to access request

    if mother != '':
        form = PersonAdminForm
        form.initial={'mother':Person.objects.get(id=mother)}

Well, this ain't working. Even if I only try to define a hardcoded initial value, it doesn`t work.

What am I doing wrong?

PS.: Of course, I may be asking the wrong questions, so I appreciate any help that solves the problem.

djvg
  • 11,722
  • 5
  • 72
  • 103
pedrovgp
  • 767
  • 9
  • 23

3 Answers3

5

My solution:

class PersonAdmin(admin.ModelAdmin):
    form = PersonAdminForm
    # ...
    def get_form(self, request, obj=None, *args, **kwargs):
        form = super(PersonAdmin, self).get_form(request, *args, **kwargs)
        # Initial values
        form.base_fields['mother'].initial = None
        if obj and obj.mother:
            form.base_fields['mother'].initial = obj.mother
        return form
Moreno
  • 1,567
  • 1
  • 12
  • 15
  • 1
    Hi, it works as well. And it is actually more versatile, so I am setting this one as the correct answer. Took me a while to try something similar again and find your answer to my own question :P – pedrovgp Sep 18 '14 at 22:54
  • Why do you do `form = PersonAdminForm` at class scope? – a06e Sep 01 '15 at 15:54
  • Usually to add some custom behavior https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#adding-custom-validation-to-the-admin – Moreno Sep 01 '15 at 19:40
1

Oh, it happens to be a lot easier than I thought.

If you pass a GET parameter with the name of the field as key to a Django`s add form, the GET parameters value will be set as initial value for that field.

In my case, I just needed to redirect to

localhost/admin/my_app/person/add/?&mother=< id >

There was no need for manipulating admin or anything.

pedrovgp
  • 767
  • 9
  • 23
0

Try overriding the get_form() method on ModelAdmin:

    class PersonAdmin(admin.ModelAdmin):
        form = PersonAdminForm

        def get_form(self, request, *args, **kwargs):
            form = super(PersonAdmin, self).get_form(request, *args, **kwargs)
            mother = request.GET.get('mother', None)
            if mother:
                form.initial = {'mother': Person.objects.get(id=mother)}
            return form
drewman
  • 1,565
  • 11
  • 15
  • Almost there! It worked for accessing the request. But somehow defining initial does not work. Neither this way nor any other. I just upgraded from Django 1.3 to 1.4, but it didn't do any well. – pedrovgp Oct 10 '12 at 00:48