A did a function that would download the avatar of the user from his social network and uses it as our site avatar. Am using django 1.5 and boto with S3 storage for uploaded media..
The function I did works perfectly when running local, but for some reason when running on boto its throwing an exception. Below is the code am using
utils.py
# -*- coding: utf-8 -*-
import json
import urllib2
import requests
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile
def download_photo(url):
"""
"""
r = requests.get(url)
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(r.content)
img_temp.flush()
return File(img_temp)
def graph_fb_profile_image(fb_uid, size=48):
url = 'http://graph.facebook.com/%s?fields=picture.height(%s).width(%s)' % (fb_uid, size, size)
request = urllib2.Request(url)
protocol = urllib2.build_opener()
response = protocol.open(request)
resp_json = json.load(response)
avatar = resp_json.get('picture').get('data').get('url')
return avatar
views.py
# get user avatar from facebook
avatar_url = graph_fb_profile_image(kwargs['response'].get('id'), 320)
user.avatar_src.save('avatar_%s.jpg' % (user.id,), download_photo(avatar_url), save=True)
The stack error am getting is following
Traceback (most recent call last):
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/newrelic-1.11.0.55/newrelic/api/object_wrapper.py", line 216, in __call__
self._nr_instance, args, kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/newrelic-1.11.0.55/newrelic/hooks/framework_django.py", line 475, in wrapper
return wrapped(*args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
return view_func(*args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/decorators.py", line 29, in wrapper
return func(request, request.social_auth_backend, *args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/views.py", line 42, in complete
return complete_process(request, backend, *args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/views.py", line 111, in complete_process
user = auth_complete(request, backend, *args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/views.py", line 196, in auth_complete
*xargs, **xkwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 373, in continue_pipeline
return authenticate(*args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 59, in authenticate
user = backend.authenticate(**credentials)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 107, in authenticate
out = self.pipeline(pipeline, *args, **kwargs)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 136, in pipeline
result = func(*args, **out) or {}
File "/var/www/snowflake-env/snowflake/snowflake/apps/accounts/pipeline.py", line 45, in set_user_details
user.avatar_src.save('avatar_%s.jpg' % (user.id,), download_photo(avatar_url), save=True)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/django/db/models/fields/files.py", line 86, in save
self.name = self.storage.save(name, content)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/django/core/files/storage.py", line 48, in save
name = self._save(name, content)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/storages/backends/s3boto.py", line 282, in _save
reduced_redundancy=self.reduced_redundancy)
File "/var/www/snowflake-env/local/lib/python2.7/site-packages/boto/s3/key.py", line 1112, in set_contents_from_file
raise AttributeError('fp is at EOF. Use rewind option '
AttributeError: fp is at EOF. Use rewind option or seek() to data start.
any advise would be appreciated.
OK, I found an answer, I needed to add seek(0) to my function and make it as following
def download_photo(url):
"""
"""
r = requests.get(url)
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(r.content)
img_temp.flush()
img_temp.seek(0)
return File(img_temp)
this solved the problem for me
Related
I am trying to upload a file to dropbox using django restframework. I am running the app on heroku. I am getting the following error :
SuspiciousFileOperation at /file/upload/
Detected path traversal attempt in '/app/media/Resume/Lal.pdf'
I have deployed the app on heroku as I am getting below path issue in my local machine
ValidationError at /file/upload/
'C:/Apisero/practice/Django_Projects/fileuploadpocusingparser/media/Resume/Lal.pdf' did not match pattern '(/(.|[\r\n])*|id:.*)|(rev:[0-9a-f]{9,})|(ns:[0-9]+(/.*)?)'
This is first time I am using dropbox with django and I have tried my best to find the issue but I couldn't. TIA.
Traceback:
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/app/file_app/views.py", line 14, in post
file_serializer.save()
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/serializers.py", line 212, in save
self.instance = self.create(validated_data)
File "/app/.heroku/python/lib/python3.10/site-packages/rest_framework/serializers.py", line 962, in create
instance = ModelClass._default_manager.create(**validated_data)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py", line 453, in create
obj.save(force_insert=True, using=self.db)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 739, in save
self.save_base(using=using, force_insert=force_insert,
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 776, in save_base
updated = self._save_table(
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 881, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 919, in _do_insert
return manager._insert(
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1415, in execute_sql
for sql, params in self.as_sql():
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1358, in as_sql
value_rows = [
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1310, in pre_save_val
return field.pre_save(obj, add=True)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/fields/files.py", line 302, in pre_save
file.save(file.name, file.file, save=False)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/fields/files.py", line 89, in save
self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/files/storage.py", line 56, in save
validate_file_name(name, allow_relative_path=True)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/files/utils.py", line 18, in validate_file_name
raise SuspiciousFileOperation(
Exception Type: SuspiciousFileOperation at /file/upload/
Exception Value: Detected path traversal attempt in '/app/media/Resume/Lal_Jan_Basha_Resume.pdf-4-1_d8crH6p.pdf'
These are all the files:
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
DEFAULT_FILE_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DROPBOX_OAUTH2_TOKEN = 'xxxxxxxxx'
DROPBOX_ROOT_PATH = 'media/'
models.py:
from django.db import models
class File(models.Model):
file = models.FileField(upload_to='Resume')
serializers.py:
from rest_framework import serializers
from .models import File
class FileSerializer(serializers.ModelSerializer):
class Meta():
model = File
fields = '__all__'
views.py :
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import status
from .serializers import FileSerializer
class FileView(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
# return Response('Hello')
file_serializer = FileSerializer(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
So I have a model like this
from django.db import models
from sorl.thumbnail import get_thumbnail
class Upload(BaseModel):
#staticmethod
def upload_path_handler(instance, filename):
return f'boxes/{instance.box.id}/uploads/{filename}'
#staticmethod
def thumbnail_path_handler(instance, filename):
return f'boxes/{instance.box.id}/thumbnails/{filename}'
def save(self, *args, **kwargs):
if self._state.adding:
# we cache the file size and store
# it into the database to improve performance
# we cannot edit the object's file so we don't
# bother to modify the file size on updates
self.size = self.file.size
super(Upload, self).save(*args, **kwargs)
thumbnail = get_thumbnail(self.file, '1280x720', crop='center')
# sorl is not saving the thumbnails for non-image files
return self.thumbnail.save(thumbnail.name, ContentFile(thumbnail.read()), True)
super(Upload, self).save(*args, **kwargs)
objects = api_managers.UploadManager()
size = models.PositiveBigIntegerField()
name = models.CharField(max_length=100, default='untitled', validators=[MinLengthValidator(2)])
channel = models.ForeignKey('api_backend.Channel', on_delete=models.CASCADE, editable=False)
box = models.ForeignKey('api_backend.Box', on_delete=models.CASCADE, editable=False)
owner = models.ForeignKey('api_backend.User', on_delete=models.CASCADE, editable=False)
thumbnail = models.ImageField(max_length=512, upload_to=thumbnail_path_handler.__func__, null=True, blank=True)
file = models.FileField(max_length=512, upload_to=upload_path_handler.__func__)
REQUIRED_FIELDS = [file, owner]
the file field can be literally any file, and I want sorl-thumbnail to make a thumbnail for the same and save it into the thumbnail field. I am on windows and am using ImageMagick. [python version- 32 bits]
this is the binary distribution I installed.
https://imagemagick.org/script/download.php
ImageMagick-7.0.10-61-Q16-x86-dll.exe Win32 dynamic at 16 bits-per-pixel component
settings.py
THUMBNAIL_ENGINE = 'sorl.thumbnail.engines.convert_engine.Engine'
However, whenever an upload-model is saved, I get the following error.
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\iyapp\\PycharmProjects\\rebox\\media\\cache\\db\\5a\\db5a88e1d6a08cdfa1afbc92e9b8cb47.jpg'
Full traceback:
Exception ignored in: <function TemporaryFile.__del__ at 0x04184610>
Traceback (most recent call last):
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\files\temp.py", line 61, in __del__
self.close()
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\files\temp.py", line 49, in close
if not self.close_called:
AttributeError: 'TemporaryFile' object has no attribute 'close_called'
__init__() got an unexpected keyword argument 'delete'
Traceback (most recent call last):
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\sorl\thumbnail\base.py", line 104, in get_thumbnail
source_image = default.engine.get_image(source)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\sorl\thumbnail\engines\convert_engine.py", line 76, in get_image
with NamedTemporaryFile(mode='wb', delete=False) as fp:
TypeError: __init__() got an unexpected keyword argument 'delete'
Remote file [boxes/2/uploads/a243bfbd00fdcb54982faf63cfc290b1dfcd47f1c0484facbd67c8b8ff606aff.jpg] at [1280x720] does not exist
exc: [Errno 2] No such file or directory: 'C:\\Users\\iyapp\\PycharmProjects\\rebox\\media\\cache\\db\\5a\\db5a88e1d6a08cdfa1afbc92e9b8cb47.jpg'
Internal Server Error: /api/channels/1/uploads/
Traceback (most recent call last):
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\asgiref\sync.py", line 339, in thread_handler
raise exc_info[1]
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\handlers\exception.py", line 38, in inner
response = await get_response(request)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\handlers\base.py", line 233, in _get_response_async
response = await wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\asgiref\sync.py", line 304, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "c:\python38\lib\asyncio\tasks.py", line 455, in wait_for
return await fut
File "c:\python38\lib\concurrent\futures\thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\asgiref\sync.py", line 343, in thread_handler
return func(*args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\generics.py", line 242, in post
return self.create(request, *args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\mixins.py", line 19, in create
self.perform_create(serializer)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\mixins.py", line 24, in perform_create
serializer.save()
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "C:\Users\iyapp\PycharmProjects\rebox\api_backend\serializers\partial.py", line 35, in create
return super(PartialUploadSerializer, self).create(validated_data)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\rest_framework\serializers.py", line 939, in create
instance = ModelClass._default_manager.create(**validated_data)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\db\models\query.py", line 447, in create
obj.save(force_insert=True, using=self.db)
File "C:\Users\iyapp\PycharmProjects\rebox\api_backend\models\uploads.py", line 43, in save
return self.thumbnail.save(thumbnail.name, ContentFile(thumbnail.read()), True)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\sorl\thumbnail\images.py", line 162, in read
f = self.storage.open(self.name)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\files\storage.py", line 36, in open
return self._open(name, mode)
File "C:\Users\iyapp\Envs\rebox_django\lib\site-packages\django\core\files\storage.py", line 231, in _open
return File(open(self.path(name), mode))
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\iyapp\\PycharmProjects\\rebox\\media\\cache\\db\\5a\\db5a88e1d6a08cdfa1afbc92e9b8cb47.jpg'
Can someone please help me fix this?
thanks a lot!
as far as I know this is why the first exception arises.
from django.core.files.temp import NamedTemporaryFile
https://github.com/jazzband/sorl-thumbnail/blob/master/sorl/thumbnail/engines/convert_engine.py#L8
this import returns a TemporaryFile
(see source code)
"""
The temp module provides a NamedTemporaryFile that can be reopened in the same
process on any platform. Most platforms use the standard Python
tempfile.NamedTemporaryFile class, but Windows users are given a custom class.
This is needed because the Python implementation of NamedTemporaryFile uses the
O_TEMPORARY flag under Windows, which prevents the file from being reopened
if the same flag is not provided [1][2]. Note that this does not address the
more general issue of opening a file for writing and reading in multiple
processes in a manner that works across platforms.
The custom version of NamedTemporaryFile doesn't support the same keyword
arguments available in tempfile.NamedTemporaryFile.
1: https://mail.python.org/pipermail/python-list/2005-December/336957.html
2: https://bugs.python.org/issue14243
"""
import os
import tempfile
from django.core.files.utils import FileProxyMixin
__all__ = ('NamedTemporaryFile', 'gettempdir',)
if os.name == 'nt':
class TemporaryFile(FileProxyMixin):
"""
Temporary file object constructor that supports reopening of the
temporary file in Windows.
Unlike tempfile.NamedTemporaryFile from the standard library,
__init__() doesn't support the 'delete', 'buffering', 'encoding', or
'newline' keyword arguments.
"""
def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='', dir=None):
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
self.name = name
self.file = os.fdopen(fd, mode, bufsize)
self.close_called = False
# Because close can be called during shutdown
# we need to cache os.unlink and access it
# as self.unlink only
unlink = os.unlink
def close(self):
if not self.close_called:
self.close_called = True
try:
self.file.close()
except OSError:
pass
try:
self.unlink(self.name)
except OSError:
pass
def __del__(self):
self.close()
def __enter__(self):
self.file.__enter__()
return self
def __exit__(self, exc, value, tb):
self.file.__exit__(exc, value, tb)
NamedTemporaryFile = TemporaryFile
else:
NamedTemporaryFile = tempfile.NamedTemporaryFile
gettempdir = tempfile.gettempdir
and the TemporayFile class' init method doesn't take any parameter named delete. instead, only tempfile.NamedTemporaryFile does. Therefore, this chunk of code fails.
def get_image(self, source):
"""
Returns the backend image objects from a ImageFile instance
"""
with NamedTemporaryFile(mode='wb', delete=False) as fp:
fp.write(source.read())
return {'source': fp.name, 'options': OrderedDict(), 'size': None}
https://github.com/jazzband/sorl-thumbnail/blob/master/sorl/thumbnail/engines/convert_engine.py#L72
I think that because of this the file isn't being saved at all.
And at last, inside the save method of the model,
We see the backend raise that the file doesn't exist.
After a user is deleted, the tokens on the client side are still valid until the time has expired. The issue is django restframwework does not handle a request from a deleted user and causes a 500. How can I prevent this?
aceback (most recent call last):
File "/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/lib/python3.6/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/lib/python3.6/site-packages/rest_framework/views.py", line 493, in dispatch
self.initial(request, *args, **kwargs)
File "/lib/python3.6/site-packages/rest_framework/views.py", line 410, in initial
self.perform_authentication(request)
File "/lib/python3.6/site-packages/rest_framework/views.py", line 324, in perform_authentication
request.user
File "/lib/python3.6/site-packages/rest_framework/request.py", line 220, in user
self._authenticate()
File "/lib/python3.6/site-packages/rest_framework/request.py", line 373, in _authenticate
user_auth_tuple = authenticator.authenticate(self)
File "/lib/python3.6/site-packages/rest_framework_jwt/authentication.py", line 33, in authenticate
payload = jwt_decode_handler(jwt_value)
File "/lib/python3.6/site-packages/rest_framework_jwt/utils.py", line 105, in jwt_decode_handler
secret_key = jwt_get_secret_key(unverified_payload)
File "/lib/python3.6/site-packages/rest_framework_jwt/utils.py", line 26, in jwt_get_secret_key
user = User.objects.get(pk=payload.get('user_id'))
File "/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/lib/python3.6/site-packages/django/db/models/query.py", line 431, in get
self.model._meta.object_name
From the JWT token, you are decoding it to get the user_id - payload['user_id'].
The error is happening because of User.objects.get(pk=payload.get('user_id')).
Instead of doing a get, you could use a get_object_or_404. Use it like so:
from django.shortcuts import get_object_or_404
payload = jwt_decode_handler(jwt_value)
user = get_object_or_404 (User, pk=payload.get('user_id'))
This raises a 404 error when a user will not be found; and that will be bubbled up through your view and handlers to return a 404 statuscode.
The suggestion by Druhn Bala works but would return a 404 error which isn't ideal for my use case. Instead I came up with one that returns a custom response. ValidationError
from rest_framework.exceptions allows you to send a 400 error with a custom response.
def jwt_decode_handler(token):
options = {
'verify_exp': api_settings.JWT_VERIFY_EXPIRATION,
}
# get user from token, BEFORE verification, to get user secret key
try:
unverified_user = jwt.decode(token, None, False)
except User.DoesNotExist:
raise ValidationError({"errors": ['Oops! Something went wrong, please logout and login back in!']})
secret_key = unverified_user.securitysettings.jwt_secret #my custom way of storing a unique jwt uuid per user.
return jwt.decode(
token,
api_settings.JWT_PUBLIC_KEY or secret_key,
api_settings.JWT_VERIFY,
options=options,
leeway=api_settings.JWT_LEEWAY,
audience=api_settings.JWT_AUDIENCE,
issuer=api_settings.JWT_ISSUER,
algorithms=[api_settings.JWT_ALGORITHM]
)
Lastly we set the custom decode handler as the default in settings.py.
JWT_AUTH = {
'JWT_DECODE_HANDLER':
'registration.decoder.jwt_decode_handler',
...
}
I want to delete a user from the database that django comes with, i entered the admin site using my superuser but when i try to delete any user manually, which i created for testing purposes, it gives the error y mentioned above, the traceback inserted below is the one from the logs.
Error
Traceback (most recent call last):
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 240, in _commit
return self.connection.commit()
sqlite3.IntegrityError: FOREIGN KEY constraint failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/options.py", line 606, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/sites.py", line 223, in inner
return view(request, *args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/utils/decorators.py", line 45, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/options.py", line 1727, in changelist_view
response = self.response_action(request, queryset=cl.get_queryset(request))
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/options.py", line 1397, in response_action
response = func(self, request, queryset)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/actions.py", line 40, in delete_selected
modeladmin.delete_queryset(request, queryset)
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/contrib/admin/options.py", line 1098, in delete_queryset
queryset.delete()
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/models/query.py", line 711, in delete
deleted, _rows_count = collector.delete()
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/models/deletion.py", line 318, in delete
sender=model, instance=obj, using=self.using
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/transaction.py", line 240, in __exit__
connection.commit()
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 262, in commit
self._commit()
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 240, in _commit
return self.connection.commit()
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/lralcocer/PycharmProjects/MediTracker/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 240, in _commit
return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
[06/May/2020 02:47:33] "POST /admin/auth/user/ HTTP/1.1" 500 142907
These is my model
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserRegister(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
first_name = models.CharField(max_length=256, default='', blank=False,)
last_name = models.CharField(max_length=256, default='', blank=False)
email = models.EmailField(unique=True, blank=False,default='')
def __str__(self):
return self.user.username
This is my form
from django import forms
from .models import *
from django.contrib.auth.models import User
#Create your forms here!
class UserRegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','password')
class UserRegisterInfoForm(forms.ModelForm):
class Meta():
model = UserRegister
fields = ('first_name','last_name','email')
This is my view
def UserRegisterFormView(request):
registered = False
if request.method == 'POST':
userform = UserRegisterForm(data=request.POST)
userinfoform = UserRegisterInfoForm(data=request.POST)
if userform.is_valid() and userinfoform.is_valid():
user = userform.save()
user.set_password(user.password)
user.save()
profile = userinfoform.save(commit=False)
profile.user = user
profile.save()
registered = True
else:
print(userform.errors, userinfoform.errors)
else:
userform = UserRegisterForm
userinfoform = UserRegisterInfoForm
return render(request,'register/register.html'{'userform':userform,'userinfoform':userinfoform,'registered':registered})
You can delete the database except the init.py file. Then run makemigrations and migrate commands again.
If that dosen't fix it, then copy all the files in that folder into another folder, delete that folder, create a new one in your project directory, then pasted everything back in (be careful with your urls.py, don't forget to change them). Then run the makemigrations and migrate commands.
I've got a Django project that throws me "FieldError: Cannot resolve keyword 'game' into field. Choices are: [list of choices]".
The funny thing is, it only occurs when DEBUG is disabled in settings.py. When DEBUG is enabled everything seems to work fine.
I have identified the code that triggers the error. My model looks like this:
from django.db import models
from django.forms import ModelForm
from time import strftime
from rostermaker.models import Player
from django.core.exceptions import ValidationError
from django.utils import timezone
class Game(models.Model):
when = models.DateTimeField(unique = True)
opponent = models.CharField(max_length = 50, default="TBD")
...
def __unicode__(self):
when = timezone.localtime(self.DateTime)
return when.strftime('%a, %b %d, %Y %I:%M %p')
class Stat(models.Model):
g = models.ForeignKey(Game, related_name = 'stat_game')
player = models.ForeignKey(Player, related_name = 'stat_player', limit_choices_to={'active': True})
...
In admin.py, the .count and .filter lines trigger the error:
def save_model(self, request, obj, form, change):
obj.save()
form.save_m2m()
count = obj.players.count()
women = obj.players.filter(sex='F')
women_count = women.count()
if count != 0:
women_pct = int((women_count/float(count))*100)
self.message_user(request,"Players scheduled: %s | Women: %s percent" % (count, women_pct))
else:
self.message_user(request,"Players scheduled: 0 | Women: 0 percent")
In a couple of views, lines similar to this one cause the error:
played_games_list = Game.objects.filter(DateTime__lte=timezone.now()).order_by('-when')
I'm using Django version 1.4 and PostgreSQL 8.4.20.
My best guess from what I've read here is that the Game class isn't loading properly. But why it appears to load properly when DEBUG is on mystifies me.
Any help is appreciated.
UPDATE: Traceback, as requested:
Traceback (most recent call last):
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/contrib/admin/options.py", line 366, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/utils/decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/views/decorators/cache.py", line 89, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/contrib/admin/sites.py", line 196, in inner
return view(request, *args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/utils/decorators.py", line 25, in _wrapper
return bound_func(*args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/utils/decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/utils/decorators.py", line 21, in bound_func
return func(self, *args2, **kwargs2)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/transaction.py", line 224, in inner
return func(*args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/contrib/admin/options.py", line 955, in add_view
self.save_model(request, new_object, form, False)
File "/home/bwareham/webapps/mprsb/myproject/rostermaker/admin.py", line 69, in save_model
count = obj.players.count()
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/manager.py", line 119, in count
return self.get_query_set().count()
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/fields/related.py", line 567, in get_query_set
return super(ManyRelatedManager, self).get_query_set().using(db)._next_is_sticky().filter(**self.core_filters)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/query.py", line 624, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/query.py", line 642, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/sql/query.py", line 1250, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/sql/query.py", line 1122, in add_filter
process_extras=process_extras)
File "/home/bwareham/webapps/mprsb/lib/python2.7/django/db/models/sql/query.py", line 1316, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'game' into field. Choices are: Hall of Fame, active, alias, battingchamps, bombat, captains, firstName, goldengloves, id, lastName, mostimproved, mvp, photo, rookies, roster, sex, walker, whippet
It was some sort of loading problem. Found solution here.
Am able to force model loading with this snippet before the admin autodiscover function in urls.py:
from django.db.models.loading import cache as model_cache
if not model_cache.loaded:
model_cache.get_models()
Thanks to all who tried to help me troubleshoot. I always learn something.