-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to remove attachments #132
Conversation
src/sa_api_v2/tests/test_views.py
Outdated
@@ -517,7 +517,7 @@ def test_GET_from_cache(self): | |||
# - SELECT * FROM sa_api_attachment AS a | |||
# WHERE a.thing_id IN (<self.place.id>); | |||
# | |||
with self.assertNumQueries(11): | |||
with self.assertNumQueries(14): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a good understanding of why these tests (this one and the next two) need an adjustment. I didn't want to delay the review any longer, but I'll look into the details of the number of queries executed here and hopefully get a better understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is fine to punt this issue for later, but we should file an issue and mark it as "technical-debt", and reference the issue as a TODO a comment on the three diffs below.
FYI here are the three queries that were added:
SELECT * FROM sa_api_place AS p
JOIN sa_api_submittedthing as t ON (p.submittedthing_ptr_id = t.id)
WHERE p.submittedthing_ptr_id = <self.place.id>;
SELECT * from sa_api_dataset AS d
WHERE d.id = <self.dataset.id>;
SELECT * FROM auth_user as u1
WHERE u1.id = <self.owner.id>;
These queries are being made because we added a new field to our Attachment serializer:
url = AttachmentIdentityField()
where we are querying for the place_id
, dataset_slug
, and owner_username
in AttachmentIdentityField. There should be a way to optimize this and avoid the extra queries, but I think we should punt this and address the issue at a later time, perhaps after the 1.8 upgrade.
src/sa_api_v2/views/base_views.py
Outdated
def partial_update(self, *args, **kwargs): | ||
attachment_id = self.kwargs['attachment_id'] | ||
obj = self.get_object_or_404(attachment_id) | ||
self.model.clear_instance_cache(obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that we have to explicitly clear the cache on a partial_update
; otherwise, deleted attachments will reappear on a page reload.
I'm not sure if this is the best way to handle cache clearing, though. Alternatively, we could overwrite partial_update
(and update
for that matter) in the CacheClearingModel
, from which several other models inherit. I have a feeling this might address #126 too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this solution makes sense for now. Note that you don't have to pass obj
to the clear_instance_cache
method:
api/src/sa_api_v2/models/caching.py
Line 27 in 47a204c
def clear_instance_cache(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the following error if I don't pass obj
to clear_instance_cache
:
TypeError: unbound method clear_instance_cache() must be called with Attachment instance as first argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that's right. I think you want to do this:
obj.clear_instance_cache()
It's essentially doing the same thing, but I would prefer this approach because it's more OO versus calling the class's method and passing in the instance.
And maybe instead of obj
we can call it something like attachment
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I have a few minor suggestions to clean up some of the code. Overall, I think this looks good!
I think we should add a test case for a PATCH on our attachment model, but I'm fine with making an issue for it and addressing it later.
src/sa_api_v2/views/base_views.py
Outdated
def partial_update(self, *args, **kwargs): | ||
attachment_id = self.kwargs['attachment_id'] | ||
obj = self.get_object_or_404(attachment_id) | ||
self.model.clear_instance_cache(obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this solution makes sense for now. Note that you don't have to pass obj
to the clear_instance_cache
method:
api/src/sa_api_v2/models/caching.py
Line 27 in 47a204c
def clear_instance_cache(self): |
src/sa_api_v2/serializers.py
Outdated
|
||
class AttachmentSerializer (EmptyModelSerializer, serializers.ModelSerializer): | ||
|
||
class AttachmentListSerializer (AttachmentSerializerMixin): | ||
file = AttachmentFileField() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this file
field is not needed because our Attachment model already has a file
field, which is being returned in the 'file': obj.file.storage.url(obj.file.name),
field of our AttachmentSerializerMixin
src/sa_api_v2/serializers.py
Outdated
file = AttachmentFileField() | ||
url = AttachmentIdentityField() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want a url
field for our attachment instance representations, as well as our attachment list representations (eg: http://localhost:8001/api/v2/smartercleanup/datasets/demo/places/3871/attachments/425)
To enable that, I think we should move this field into our AttachmentSerializerMixin.
src/sa_api_v2/serializers.py
Outdated
} | ||
fields = self.get_fields() | ||
|
||
if 'url' in fields: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we move the url = AttachmentIdentityField()
field definition to this class, then we can remove this check
src/sa_api_v2/serializers.py
Outdated
@@ -794,7 +811,7 @@ def get_detailed_submission_sets(self, place): | |||
return details | |||
|
|||
def attachments_to_native(self, obj): | |||
return [AttachmentSerializer(a).data for a in obj.attachments.all()] | |||
return [AttachmentListSerializer(a, context=self.context).data for a in obj.attachments.all()] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this context
kwarg? All of the tests pass, and the app seems to behave fine without it.
src/sa_api_v2/tests/test_views.py
Outdated
@@ -517,7 +517,7 @@ def test_GET_from_cache(self): | |||
# - SELECT * FROM sa_api_attachment AS a | |||
# WHERE a.thing_id IN (<self.place.id>); | |||
# | |||
with self.assertNumQueries(11): | |||
with self.assertNumQueries(14): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is fine to punt this issue for later, but we should file an issue and mark it as "technical-debt", and reference the issue as a TODO a comment on the three diffs below.
FYI here are the three queries that were added:
SELECT * FROM sa_api_place AS p
JOIN sa_api_submittedthing as t ON (p.submittedthing_ptr_id = t.id)
WHERE p.submittedthing_ptr_id = <self.place.id>;
SELECT * from sa_api_dataset AS d
WHERE d.id = <self.dataset.id>;
SELECT * FROM auth_user as u1
WHERE u1.id = <self.owner.id>;
These queries are being made because we added a new field to our Attachment serializer:
url = AttachmentIdentityField()
where we are querying for the place_id
, dataset_slug
, and owner_username
in AttachmentIdentityField. There should be a way to optimize this and avoid the extra queries, but I think we should punt this and address the issue at a later time, perhaps after the 1.8 upgrade.
Closes: #59
Addresses: #126
In conjunction with mapseed/platform#983
Create a new view,
AttachmentInstanceView
, to facilitatePATCH
requests to individual attachments. Add avisible
parameter toAttachmentModel
s to allow "deletion" of attachments from the client editor.TODO: