-
Notifications
You must be signed in to change notification settings - Fork 22
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
User bookmarking #14
User bookmarking #14
Conversation
@@ -0,0 +1,12 @@ | |||
from django.core.urlresolvers import reverse |
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.
Is this file old?
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 so, I'll remove it.
Serializes a {user,entry,when} fave. | ||
""" | ||
|
||
user = '__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.
What's this do?
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.
good question @gideonthomas do you remember why we needed this? If so, we can document it in the source
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.
Actually, I don't know what this is :P I thought all serializer fields should be instances. Are you sure this is working?
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.
__all__
normally exposes all public methods for use in import ... from ...
statements including those prefixed with underscores (usually 'hidden') but in this case it doesn't look like it actually does anything, so I'll remove it.
def entries(self, instance): | ||
""" | ||
Show all entries as a string of titles. In the future we should make them links. | ||
""" | ||
print('entries instance') |
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.
Remove this logging
from rest_framework.generics import ListCreateAPIView, RetrieveAPIView | ||
from rest_framework.pagination import PageNumberPagination | ||
from rest_framework.response import Response | ||
|
||
from pulseapi.entries.models import Entry | ||
from pulseapi.entries.serializers import EntrySerializer | ||
from pulseapi.users.models import UserFavorites | ||
|
||
# FIXME: TODO: Remove the handling for GET, so that only PUT works |
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.
Is the GET there just so it's easier to test?
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.
correct. The "real" use would be PUT only, but for testing a GET is way easier to do without writing an XHR test page
|
||
# FIXME: TODO: Remove the handling for GET, so that only PUT works | ||
@api_view(['GET','PUT']) | ||
def toggle_favorite(request, entryid): |
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.
Just so I understand what's going on here because I've seen this before, can you explain line 17 and 18 from a django standpoint? Why is this a function and not a view class? Is 17 the indicator that it's a generic GET/PUT view which does nothing special?
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.
line 17 says "only expose this def
when the http verb is GET or PUT (http verb whitelist)
line 18 is a function that services a view (see urls.py) as a general function rather than a class entry, as faving an entry is technically something "outside" of entries and users.
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.
See above comment
had to 'dismiss' to get rid of a detached review comment
@@ -2,26 +2,63 @@ | |||
|
|||
from django.test import TestCase | |||
from django.test import Client | |||
from pulseapi.tests import PulseTestCase |
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.
Did my PR reset this to older code?
@@ -1,9 +1,8 @@ | |||
import json | |||
|
|||
from django.core.urlresolvers import reverse |
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.
hm, this looks to have old test code, too.
@@ -21,8 +56,8 @@ def post_validate(request): | |||
nonce = False | |||
|
|||
if request.data: | |||
csrf_token = request.data['csrfmiddlewaretoken'] | |||
nonce = request.data['nonce'] | |||
csrf_token = request.data.get('csrfmiddlewaretoken', False) |
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.
this was throwing key errors so I turned it into get
rather than direct access to get a fallback value.
REST endpoint: <PUT> /entries/<id>/bookmark Behaviour: calling the endpoint, by an authenticated user, will mark the entry as bookmarked by the that user. Calling it again unbookmarks the entry.
* User favorites route * ‘favorite’ -> ‘bookmark’ * Bookmark view tests
|
||
is_bookmarked = serializers.SerializerMethodField() | ||
|
||
def get_is_bookmarked(self, instance): |
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.
This is the kind of magic that bothers me. I understand it, but it still feels weird.
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 hate Django for this kind of thing.
from pulseapi.users.models import UserBookmarks | ||
|
||
@api_view(['PUT']) | ||
def toggle_bookmark(request, entryid): |
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.
We're sticking with the toggling behavior?
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.
After thinking about it some more, entries already say whether they are bookmarked or not when you call /entries
so for regular operation we don't need a "toggle yes or no", the only time we would need that is for bulk bookmark syncing, which we should probably do on its own dedicated route so a full set of bookmarks can be sent over in a single call.
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.
That makes sense. There's then a little bit of manual state management between the front and back end, but it seems reasonable.
@@ -21,7 +18,6 @@ class Migration(migrations.Migration): | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('name', models.CharField(max_length=140)), | |||
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='as_creator', to=settings.AUTH_USER_MODEL)), |
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 know I probably shouldn't be reading into the migrations files too much but why is this being removed?
Should we merge these and then follow up with an immediate rebuild of migrations?
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.
that would be my suggestion too, yes. It's time to wipe the compound migrations we've been accumulating (except for issues, which is one step and has data) and rebuild everything as single step migrations.
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.
This looks good, just a few clarifications before merging?
/entries
and/entries/1234
show entries/a single entry with their total fave count as fieldfavorite_count
, and a fieldis_favorite
that istrue
for a user that is a) logged in, and b) has favorited this entry. In any other case, it will befalse
./entries/123/favorite
toggles a fave/not-fave value for entry123
for the currently logged in user. If a user is not logged in, they will receive a 403fixes #12
fixes #30