Django-Channels 2 not persisting session data set in `connect` - python

channels==2.1.2 | channels-redis==2.2.1 | daphne==2.2.0 | Django==1.11.6
I've upgraded to Channels 2 specifically for the ability to access and modify the session from within a consumer (and access it in a view), but that doesn't seem to be working. Basically, I want to identify AnonymousUsers and send them messages (each his own, not all of them together).
Here's my routing.py file:
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
core.routing.websocket_urlpatterns
)
),
})
Here's my consumers.py file:
class ChatConsumer(WebsocketConsumer):
def connect(self):
if self.scope['user'].is_authenticated:
user_id = str(self.scope['user'].id)
self.scope['session']['user_identifier']= user_id
self.group_name = user_id
else:
user_id = str(self.scope['user']) + str(uuid.uuid4())
self.scope['session']['user_identifier'] = user_id
self.group_name = user_id
self.scope['session'].save()
print(f" in consumer: {self.scope['session']['user_identifier']}")
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.group_name,
self.channel_name
)
self.accept()
And in the view where I need to use send, I'm trying to get the group_name (user_identifier) from the session in case of an AnonymousUser:
def get_spotify_link(request):
if request.user.is_authenticated:
user_identifier = str(request.user.id)
else:
user_identifier = request.session['user_identifier']
print(f"in get_spotify_link: {user_identifier}")
However, I'm intermittently (well, 99% of time) getting KeyError: 'user_identifier'.
Internal Server Error: /get_spotify_link/
Traceback (most recent call last):
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/myusername/PycharmProjects/artist_notify/core/views.py", line 442, in get_spotify_link
user_identifier = request.session['user_identifier']
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 57, in __getitem__
return self._session[key]
KeyError: 'user_identifier'
[2018/07/08 20:54:03] WebSocket HANDSHAKING / [127.0.0.1:65478]
in consumer: AnonymousUser8883761c-f673-413e-82e2-413d1cbb17e3
[2018/07/08 20:54:03] WebSocket CONNECT / [127.0.0.1:65478]
Internal Server Error: /get_spotify_link/
Traceback (most recent call last):
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/myusername/PycharmProjects/artist_notify/core/views.py", line 442, in get_spotify_link
user_identifier = request.session['user_identifier']
File "/Users/myusername/.virtualenvs/bap_dev/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 57, in __getitem__
return self._session[key]
KeyError: 'user_identifier'

Related

AttributeError at /profiles/user-profile/2/ 'int' object has no attribute '_meta'

Here I am using an api of notifications. here is the reference of that api link. I have follow the instructions given on the github read me file. But when i try to send an email by actor to recipient .it shows me the error 'int' object has no attribute '_meta'. The actor field and recipient both accept user_ids and I have put them manually. But still didn't work.
profiles/Views.py
class UserProfileFollowToggle(LoginRequiredMixin,View):
login_url = '/accounts/login/'
def post(self, request, *args, **kwargs):
user_to_toggle_pk=kwargs.get('pk')
username_to_toggle = request.POST.get("username")
profile_, is_following = UserProfile.objects.toggle_follow(request.user, request.user.id, user_to_toggle_pk ,username_to_toggle)
return redirect(f'/profiles/{username_to_toggle}')
profiles/models.py
class ProfileManager(models.Manager):
def toggle_follow(self, request_user,user_id,user_to_toggle_pk, username_to_toggle):
profile_ = UserProfile.objects.get(user__username__iexact=request_user.username)
is_following = False
follower = profile_.follower.filter(username__iexact=username_to_toggle).first()
if follower:
profile_.follower.remove(follower.id)
notify.send(user_id, recipient=user_to_toggle_pk, verb='unfollow you')
else:
new_follower = User.objects.get(username__iexact=username_to_toggle)
profile_.follower.add(new_follower.id)
notify.send(user_id, recipient=user_to_toggle_pk, verb='follow you')
is_following = True
return profile_, is_following
traceback:
Traceback (most recent call last):
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\AHMED\grapPub\grabpublic\profiles\views.py", line 30, in post
profile_, is_following = UserProfile.objects.toggle_follow(request.user, request.user.id, user_to_toggle_pk ,username_to_toggle)
File "C:\Users\AHMED\grapPub\grabpublic\profiles\models.py", line 22, in toggle_follow
notify.send(user_id, recipient=user_to_toggle_pk, verb='unfollow you')
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\dispatch\dispatcher.py", line 173, in send
return [
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\dispatch\dispatcher.py", line 174, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "C:\Users\AHMED\grapPub\grabpublic\notifications\base\models.py", line 288, in notify_handler
actor_content_type=ContentType.objects.get_for_model(actor),
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\contrib\contenttypes\models.py", line 40, in get_for_model
opts = self._get_opts(model, for_concrete_model)
File "C:\Users\AHMED\anaconda3\lib\site-packages\django\contrib\contenttypes\models.py", line 27, in _get_opts
model = model._meta.concrete_model
Exception Type: AttributeError at /profiles/user-profile/2/
Exception Value: 'int' object has no attribute '_meta'
If more information is required than tell me in a comment section. I will update my question with that information.
I think the AttributeError is caused, because you are trying to pass a user pk to the send function
notify.send(user_id, recipient=user_to_toggle_pk, verb='unfollow you')
^^^^^^^^^^^^^^^^
but the send function expect an User object.
So try something like this..
user = User.objects.get(pk=user_to_toggle_pk)
notify.send(user_id, recipient=user, verb='unfollow you')

I'm trying to apply celery to Class based view(apis) in django. How can I do this?

Is it a correct way to apply celery to class based views?
And, if it is, how can I apply celery to class based Views?
I can’t apply just tagging #app.task above functions inside class.
class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
permission_classes = (IsAdmin,)
serializer_class = ScheduleSerializer
#app2.task
def get(self, request, franchise_id, start = None, end = None):
if start != None and end != None:
query1 = Q(student__profile__franchise__exact=franchise_id)
query2 = Q(start_time__gte=start)
query3 = Q(end_time__lt=end)
queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
serializer = ScheduleSerializer(queryset, many=True)
else:
query1 = Q(student__profile__franchise__exact=franchise_id)
queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')
serializer = ScheduleSerializer(queryset, many=True)
return Response(serializer.data)
I'm trying to test this api and when I call HTTP GET Method to call this api,
i get the error below:
Traceback (most recent call last):
File "C:\Users\Tonyscoding\Desktop\TOCOL\TOCOL_backend\api\testing\test_pagination.py", line 154, in test_admin_schedule_pagination
response = self.client.get('/api/schedule/by/franchise/simple/1/')
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 286, in get
response = super().get(path, data=data, **extra)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 203, in get
return self.generic('GET', path, **r)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 232, in generic
method, path, data, content_type, secure, **extra)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 422, in generic
return self.request(**r)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 283, in request
return super().request(**kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 235, in request
request = super().request(**kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 503, in request
raise exc_value
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\local.py", line 191, in __call__
return self._get_current_object()(*a, **kw)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\app\task.py", line 392, in __call__
return self.run(*args, **kwargs)
TypeError: get() missing 1 required positional argument: 'request'
my celery worker get the task. I think it's not a worker problem..
In your case might work next scenario. Create a task for hard workload:
#app.task
def schedule_by_franchise(franchise_id, start=None, end=None):
# Do some slow workload, filtering by non-indexed fields or something.
if start is not None and end is not None: # is not None ~20% faster than != None
query1 = Q(student__profile__franchise__exact=franchise_id)
query2 = Q(start_time__gte=start)
query3 = Q(end_time__lt=end)
queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
else:
query1 = Q(student__profile__franchise__exact=franchise_id)
queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')
# Returns something serializable and what could be used for more faster DB search (founded object primary keys might fits)
return tuple(queryset.values_list('id', flat=True))
When executed first GET you should create Celery task and then save it TASK_ID somewhere to later get result:
from celery.result import AsyncResult
class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
permission_classes = (IsAdmin,)
serializer_class = ScheduleSerializer
def get(self, request, franchise_id, start=None, end=None, task_id=None):
if not task_id:
task = schedule_by_franchise.delay(franchise_id, start, end)
return Response({
'task': task.task_id,
'status': 'processing',
'message': f'Please, try again in 10 seconds with following task_id={task.task_id}',
})
else:
result = AsyncResult(task_id)
if result.ready():
ids = result.result
queryset = Schedule.objects.filter(id__in=ids)
serializer = ScheduleSerializer(queryset, many=True)
return Response(serializer.data)
else:
return Response({
'status': 'not_ready_yet',
'message': 'Please, try again in 5 seconds',
})

Django AttributeError: 'collections.OrderedDict' object has no attribute 'pk'

When I try to add an url attribute to my model I get this error:
AttributeError: 'collections.OrderedDict' object has no attribute 'pk'
These are the codes I use. I tried a lot of things but just get an error with everything I try..
Serializer:
class GroupPatchSerializer(serializers.ModelSerializer):
linked_sites = serializers.ListField()
name = serializers.CharField(required=False)
url = serializers.HyperlinkedIdentityField(
view_name="group-detail", lookup_url_kwarg="group_pk"
)
class Meta:
model = Group
fields = ("id", "url", "name", "linked_sites")
def validate_linked_sites(self, sites):
** code **
return sites
# noinspection PyMethodMayBeStatic
def validate_name(self, name):
** code **
return name
view:
def patch(self, request, group_pk):
"""
Add site to group, change an existing group's name.
-id: The group's id
"""
user = request.user
group_id = int(group_pk)
group = Group.objects.filter(pk=group_id).first()
# Update the group
serializer_class = self.get_serializer_class()
serializer = serializer_class(
data=self.request.data,
context={"request": request, "user_pk": user.id, "group_id": group_id},
)
test-class:
def test_ok_authorized_access(self):
# Login the user
self.client.force_login(self.user_1)
UserSiteFactory(user=self.user_1, site=self.test_site_3)
# Get the url
url = reverse("group-detail", kwargs={"group_pk": self.test_group_1.pk})
# New group name
new_name = "New group name"
sites = [self.test_site_3.pk]
# Execute the patch operation
response = self.client.patch(
url, data={"name": new_name, "linked_sites": sites}
)
# Test if there was no error
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Test if the group was renamed
group = Group.objects.all().filter(pk=self.test_group_1.pk).first()
self.assertEqual(group.name, new_name)
stacktrace
Traceback (most recent call last):
File "/opt/project/backend/groups/tests/test_group_patch.py", line 45, in test_ok_authorized_access
url, data={"name": new_name, "linked_sites": sites}
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 310, in patch
path, data=data, format=format, content_type=content_type, **extra)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 215, in patch
return self.generic('PATCH', path, data, content_type, **extra)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 232, in generic
method, path, data, content_type, secure, **extra)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 422, in generic
return self.request(**r)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 283, in request
return super().request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 235, in request
request = super().request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 503, in request
raise exc_value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/opt/project/backend/groups/views/group_detail_view.py", line 108, in patch
return Response(serializer.data, status=status.HTTP_200_OK)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 559, in data
ret = super().data
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 263, in data
self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 526, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 393, in to_representation
url = self.get_url(value, self.view_name, request, format)
File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 329, in get_url
lookup_value = getattr(obj, self.lookup_field)
AttributeError: 'collections.OrderedDict' object has no attribute 'pk'
From the DRF docs on HyperlinkedIdentityField:
lookup_field - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is 'pk'.
lookup_url_kwarg - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as lookup_field.
So you're setting lookup_url_kwarg directly, but you're not changing lookup_field, which is where your error is coming from. Because lookup_url_kwarg defaults to the same value as lookup_field, we can just use that:
class GroupPatchSerializer(serializers.ModelSerializer):
# code...
url = serializers.HyperlinkedIdentityField(
view_name="group-detail", lookup_field="group_pk"
)
# code...

Python-Django program working in Postman but not working on connecting to an iOS app

I have a created a simple Python program, which will retrieve and add data to database based on the user input. I used POST method for this. The program is successfully working in Postman, but when I call the program from an iOS app using API call, the program is showing 500 error. The errors are in exception.py and base.py. My program is given below
#api_view(["POST"])
def mg_grt(request):
if request.method == 'POST':
name = request.POST['name']
word = name.lower()
greet = Greet.objects.filter(grett=word)
if greet != 0:
d = Resp(rsp=word)
d.save()
r_val = Resp.objects.all()
rt = random.choice(r_val)
return HttpResponse(rt)
else:
return HttpResponse("Sorry...I didn't understand")
else:
return HttpResponse("Bad Request")
The errors are:
File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 53, in handler
return func(*args, **kwargs)
File "/Users/abijith/Test5/tgpi/views.py", line 21, in mg_grt
name = request.POST['name']
File "/Library/Python/2.7/site-packages/django/utils/datastructures.py", line 85, in __getitem__
raise MultiValueDictKeyError(repr(key))
MultiValueDictKeyError: "u'name'"
[31/Aug/2018 10:20:45] "POST /grt/ HTTP/1.1" 500 14099

Read and process multiple json files in python

I'm trying to process many json files with user input.
If there are three indentical data ["a","a","a"] in GeneListA, I suppose it is going to run the code three times with
jsonurl = "http://abc.def/a/format=json"
However, I got the error :
Traceback (most recent call last):
File "/Users/me/miniconda3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/me/miniconda3/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/me/miniconda3/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/me/Desktop/Project/gsea/analysis/views.py", line 49, in result
for gene in data[0][gidA]:
KeyError: 'NC_000913\r\nNC_000913\r\nNC_000913'
And here is my code:
AGOAnnos = []
for genefromlist in GeneListA:
jsonurl = "http://abc.def/"+genefromlist+"/format=json"
print(jsonurl)
with urllib.request.urlopen(jsonurl) as url:
data = json.loads(url.read().decode())
for gene in data[0][gidA]:
for anno in data[0][gidA][gene]:
if type(anno) is dict:
GOAnno = re.search(r'GO:\d+',anno["ID"])
if GOAnno:
AGOAnnos.append(GOAnno.group())
elif type(anno) is str:
GOAnno = re.search(r'GO:\d+',anno)
if GOAnno:
AGOAnnos.append(GOAnno.group())
I can't find what are the values of variables (gidA / gene) in your code.
The error raised because the in the data response there is no key with gidA

Categories