strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
391 stars 115 forks source link

File fields are broken in create mutation #461

Closed yergom closed 5 months ago

yergom commented 5 months ago

File fields are not correctly handled during full clean, but they are also not saved to the database. The following is an analysis of the code of some snippets of https://github.com/strawberry-graphql/strawberry-graphql-django/blob/main/strawberry_django/mutations/resolvers.py:


dummy_instance = model()
_, create_kwargs, files, m2m = prepare_create_update(
    info=info,
    instance=dummy_instance,
    data=data,
    full_clean=full_clean,
    key_attr=key_attr,
)
# dummy_instance does not have file fields set, as prepare_create_update is only collecting the files

full_clean_options = full_clean if isinstance(full_clean, dict) else {}
if full_clean:
    dummy_instance.full_clean(**full_clean_options)  # type: ignore
    # full_clean fails if a file had, for example, Blank=False

instance = model._default_manager.create(**create_kwargs)
# instance is created (without file fields)
for file_field, value in files:
    file_field.save_form_data(instance, value)
   # save_form_data implementation DOES NOT save the instance
for field, value in m2m:
    update_m2m(info, instance, field, value, key_attr)
  #The instance is returned without saving!
return instance

Note that the update mutation is correctly implemented:

instance, _, files, m2m = prepare_create_update(
      info=info,
      instance=instance,
      data=data,
      key_attr=key_attr,
      full_clean=full_clean,
  )

  for file_field, value in files:
      file_field.save_form_data(instance, value)

  if pre_save_hook is not None:
      pre_save_hook(instance)

  full_clean_options = full_clean if isinstance(full_clean, dict) else {}
  if full_clean:
      instance.full_clean(**full_clean_options)  # type: ignore

  instance.save()

System Information

Upvote & Fund

Fund with Polar