api: ignore deleted users when using update/get_or_create (#51368)

This commit is contained in:
Benjamin Dauvergne 2021-02-23 15:14:32 +01:00
parent 49233873d4
commit ebd152fe86
2 changed files with 18 additions and 13 deletions

View File

@ -41,34 +41,28 @@ class GetOrCreateMixinView(object):
def _get_lookup_keys(self, name):
return self.request.GET.getlist(name)
def _get_model_class(self):
serializer_class = self.get_serializer_class()
return serializer_class.Meta.model
def _lookup_instance(self, keys):
ModelClass = self._get_model_class()
kwargs = {}
for key in keys:
try:
kwargs[key] = self.request.data[key]
except KeyError:
raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: ['key %r is missing' % key]})
qs = self.get_queryset()
try:
return ModelClass.objects.get(**kwargs)
except ModelClass.DoesNotExist:
return qs.get(**kwargs)
except qs.model.DoesNotExist:
return None
except ModelClass.MultipleObjectsReturned:
except qs.model.MultipleObjectsReturned:
raise Conflict('retrieved several instances of model %s for key attributes %s' % (
ModelClass.__name__, kwargs))
qs.model.__name__, kwargs))
def _validate_get_keys(self, keys):
ModelClass = self._get_model_class()
# Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
info = model_meta.get_field_info(self.get_queryset().model)
errors = []
for key in keys:
if key not in info.fields:

View File

@ -1462,6 +1462,17 @@ def test_api_users_get_or_create(settings, app, admin):
assert User.objects.get(id=id).password != password
assert User.objects.get(id=id).check_password('secret')
# do not get deleted user, create a new one
User.objects.get(id=id).mark_as_deleted()
payload['last_name'] = 'Doe'
resp = app.post_json('/api/users/?get_or_create=email', params=payload, status=201)
assert id != resp.json['id']
id = resp.json['id']
assert User.objects.get(id=id).first_name == 'Jane'
assert User.objects.get(id=id).last_name == 'Doe'
assert User.objects.get(id=id).password != password
assert User.objects.get(id=id).check_password('secret')
def test_api_users_get_or_create_email_is_unique(settings, app, admin):
settings.A2_EMAIL_IS_UNIQUE = True