1

I have a model with generic relation like this:

  content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True)

  object_id = models.PositiveIntegerField(blank=True, null=True)

  content_object = GenericForeignKey('content_type', 'object_id')

To make the life easier for the user I have modified the form. The idea was to have one field with choices instead of multiple. For that I have merged fields into choices inside of form's init().

def __init__(self, *args, **kwargs):
    super(AdminTaskForm, self).__init__(*args, **kwargs)

    # combine object_type and object_id into a single 'generic_obj' field
    # getall the objects that we want the user to be able to choose from
    available_objects = list(Event.objects.all())
    available_objects += list(Contest.objects.all())

    # now create our list of choices for the <select> field
    object_choices = []
    for obj in available_objects:
        type_id = ContentType.objects.get_for_model(obj.__class__).id
        obj_id = obj.id
        form_value = "type:%s-id:%s" % (type_id, obj_id)  # e.g."type:12-id:3"
        display_text = str(obj)
        object_choices.append([form_value, display_text])
    self.fields['content_object'].choices = object_choices

Till now everything was working fine, but now I have to provide initial value for content_object field.

I have added this code to init() but it is not working:

    initial = kwargs.get('initial')
    if initial:
        if initial['content_object']:
            object = initial['content_object']
            object_id = object.id
            object_type = ContentType.objects.get_for_model(object).id
            form_value = "type:%s-id:%s" % (object_type, object_id)
            self.fields['content_object'].initial = form_value

Any suggestions why I cannot set initial value inside of init? Thanks!

P.S. Debug output looks for me ok, but initial is not set at all.

print(self.fields['content_object'].choices) --> [['type:32-id:10050', 'Value1'], ['type:32-id:10056', 'Value2']]
print(form_value) --> type:32-id:10056
Alexander Tyapkov
  • 4,837
  • 5
  • 39
  • 65

1 Answers1

2

I have found a nice answer to my question here:

If you have already called super().init in your Form class, you should update the form.initial dictionary, not the field.initial property. If you study form.initial (e.g. print self.initial after the call to super().init), it will contain values for all the fields. Having a value of None in that dict will override the field.initial value

The solution to the problem was then just adding one additional line:

self.initial['content_object'] = form_value
Community
  • 1
  • 1
Alexander Tyapkov
  • 4,837
  • 5
  • 39
  • 65