For our wagtail site, I'm trying to override the save method of our custom document class to dynamically create a thumbnail image of pdf files that are uploaded. Then I would like those thumbnails to be available in the admin's image menu so they can be used around the website.
I can create the thumbnail and save it correctly on our folder for uploaded images, but they don't show on the image selector. I assumed it was because even though they are in the folder they are not on the database so tried creating an instance of our custom image class for the thumbnail image, and now when I try to load the admin image menu I get a "Rendition does not exist" error.
Following the wagtail documentation I do have a CustomRendition model and I understand that I probably need to manually create the renditions for the thumbnails. My questions is how? because I don't know how to get the filter_spec and focal_point_key fields
Here are the code snippets,
CustomDocument save method:
def save(self, *args, **kwargs):
#check if this is a new document
if self._state.adding is True:
#save to get pk, file paths and such
super(CustomDocument, self).save(*args, **kwargs)
#check if it is pdf
if self.file.name[-3:] == "pdf":
pdf_file_path = self.file.path
thumbnail_name_start = self.file.name.find('/')
thumbnail_name = self.file.name[thumbnail_name_start + 1 :-4] + "_thumbnail.jpeg"
thumbnail_path = MEDIA_ROOT + "/uploaded_images/"
#create thumbnail
pdf_thumbnail = convert_from_path(
pdf_file_path,
first_page=1,
last_page=1,
output_file = thumbnail_name,
output_folder = thumbnail_path,
fmt="jpeg",
size=(77, 100))[0]
#create custom image model instance
thumbnail = CustomImage.objects.create(
file=ImageFile(pdf_thumbnail),
publication_year=self.publication_year,
width = 77,
height = 100
)
#thumbnail.author and self.author are ParentalManytoMany keys to our user profiles.
thumbnail.author = self.author.all()
thumbnail.save()
else:
super(CustomDocument, self).save(*args, **kwargs)
CustomRendition model
class CustomRendition(AbstractRendition):
image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name="renditions")
class Meta:
unique_together = (("image", "filter_spec", "focal_point_key"),)
Full error trace
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 381, in get_rendition
rendition = self.find_existing_rendition(filter)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 436, in find_existing_rendition
raise Rendition.DoesNotExist
common.models.CustomRendition.DoesNotExist
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\core\handlers\base.py", line 220, in _get_response
response = response.render()
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\admin\auth.py", line 197, in overridden_render
return render()
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\response.py", line 114, in render
self.content = self.rendered_content
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\response.py", line 92, in rendered_content
return template.render(context, self._request)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\backends\django.py", line 62, in render
return self.template.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 175, in render
return self._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 157, in render
return compiled_parent._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 157, in render
return compiled_parent._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 157, in render
return compiled_parent._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 157, in render
return compiled_parent._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 157, in render
return compiled_parent._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 63, in render
result = block.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 63, in render
result = block.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 208, in render
return template.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 177, in render
return self._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\defaulttags.py", line 322, in render
return nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\defaulttags.py", line 238, in render
nodelist.append(node.render_annotated(context))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\loader_tags.py", line 208, in render
return template.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 177, in render
return self._render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 1005, in <listcomp>
return SafeString("".join([node.render_annotated(context) for node in self]))
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\template\base.py", line 966, in render_annotated
return self.render(context)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\templatetags\wagtailimages_tags.py", line 113, in render
rendition = get_rendition_or_not_found(image, self.filter)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\shortcuts.py", line 13, in get_rendition_or_not_found
return image.get_rendition(specs)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 383, in get_rendition
rendition = self.create_rendition(filter)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 468, in create_rendition
defaults={"file": self.generate_rendition_file(filter)},
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 498, in generate_rendition_file
generated_image = filter.run(self, BytesIO())
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 647, in run
with image.get_willow_image() as willow:
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\contextlib.py", line 135, in __enter__
return next(self.gen)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 186, in get_willow_image
with self.open_file() as image_file:
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\contextlib.py", line 135, in __enter__
return next(self.gen)
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 161, in open_file
if self.is_stored_locally():
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\wagtail\images\models.py", line 130, in is_stored_locally
self.file.path
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\db\models\fields\files.py", line 60, in path
self._require_file()
File "C:\ProgramData\Anaconda3\envs\wagtail\lib\site-packages\django\db\models\fields\files.py", line 40, in _require_file
raise ValueError(
ValueError: The 'file' attribute has no file associated with it.
The error shows when I go to the image menu in the admin panel after uploading the document.
I've tried searching here for similar situations and so far have not found anything close to the problem I'm having.
Related
I am attempting my first React + DRF project. Here is my difficulty. When I try to create a user with an existing username I get a 500 internal server error and I can't seem to catch it or do anything with it in React. It otherwise works perfectly well and I can display errors when retrieving user info (such as: "sure does not exist").
The full traceback of the IntegrityError error I get from the backend is:
Traceback (most recent call last):
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "users_customuser_username_key"
DETAIL: Key (username)=(kenshiro) already exists.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/views/generic/base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/bernardino/Desktop/boombust/users/views.py", line 33, in post
user = serializer.save()
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/rest_framework/serializers.py", line 212, in save
self.instance = self.create(validated_data)
File "/Users/bernardino/Desktop/boombust/users/serializers.py", line 59, in create
instance.save()
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/contrib/auth/base_user.py", line 68, in save
super().save(*args, **kwargs)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/base.py", line 806, in save
self.save_base(
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/base.py", line 857, in save_base
updated = self._save_table(
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/base.py", line 1000, in _save_table
results = self._do_insert(
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/base.py", line 1041, in _do_insert
return manager._insert(
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/query.py", line 1434, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1621, in execute_sql
cursor.execute(sql, params)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 103, in execute
return super().execute(sql, params)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/bernardino/Desktop/boombust/.env/lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "users_customuser_username_key"
DETAIL: Key (username)=(kenshiro) already exists.
The view in views.py is:
class CustomUserCreate(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request, format='json'):
serializer = CustomUserSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
try:
user = serializer.save()
if user:
json = serializer.data
return Response(json, status=status.HTTP_201_CREATED)
except IntegrityError:
return Response({"error": "This username is already taken."}, status=status.HTTP_406_NOT_ACCEPTABLE)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
And this is the React logic:
const onSubmit = async (values) => {
const user = {
first_name: values.firstName,
last_name: values.lastName,
username: values.username,
email: values.email,
password: values.password,
};
const response = await fetch(`users/user/create/`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({...user}),
}).catch(err => err);
const text = await response.text();
console.log(response.status);
if (response.status === 201) {
console.log("success", JSON.parse(text));
} else {
console.log("failed", text);
}
};
This is the serializer from serializers.py:
class CustomUserSerializer(serializers.ModelSerializer):
token = serializers.SerializerMethodField()
password = serializers.CharField(write_only=True)
email = serializers.EmailField(
required=True
)
username = serializers.CharField(required=True)
first_name = serializers.CharField(required=True)
last_name = serializers.CharField(required=True)
password = serializers.CharField(
min_length=8, write_only=True, required=True)
class Meta:
model = CustomUser
fields = ('email', 'username', 'password', 'token', 'first_name', 'last_name')
extra_kwargs = {'password': {'write_only': True}}
def get_token(self, user):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
I do have a username = CICharField(unique=True) in the CustomUser class in models.py if it helps.
You need to check before you save the model.
class CustomUserCreate(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request, format='json'):
serializer = CustomUserSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
# here you can check if the username already exists or not
username = serializer.validated_data.get('username')
if CustomUser.objects.filter(username = username).count() > 0:
return Response({"error": "This username is already taken."}, status=status.HTTP_406_NOT_ACCEPTABLE)
# if username is new
user = serializer.save()
if user:
json = serializer.data
return Response(json, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I am having issues uploading the files using Material UI DropzoneDialogBase;
My frontend is react & backend is flask
My component is defined as below
<DropzoneDialogBase
dialogTitle={addFileClassDialogTitle()}
fileObjects={uploadFiles}
cancelButtonText={"cancel"}
submitButtonText={"submit"}
maxFileSize={5000000}
filesLimit={1}
open={fileClassState.showAddFileClassForm}
onAdd={newFile => {
console.log('onAdd', newFile);
setUploadFiles([].concat( uploadFiles , newFile ));
}}
onDelete={deleteFile => {
console.log('onDelete', deleteFile);
const fileList = [...uploadFiles];
fileList.splice( deleteFile, 1 );
setUploadFiles( fileList );
}}
onClose={() => setShowAddFileClassForm(false)}
onSave={() => saveNewFileClass( )}
showPreviews={true}
showFileNamesInPreview={true}
/>
The component works fine and adds the files to the object "uploadFiles"
This is my saveNewFileClass
const saveNewFileClass = async () => {
const credentials = localStorage.getItem("credentials");
const formData = new FormData();
formData.append("file", uploadFiles[0]);
console.log( "type of uploadfiles =>", typeof(uploadFiles[0]));
for (var key of formData.entries()) {
console.log(key[0] + ', ' + key[1]);
}
formData.append("data", JSON.stringify({ token: credentials, fileclass: newFileClass }));
console.log('onSave', uploadFiles);
console.log("save new file class", formData);
const requestOptions = {
mode: 'cors',
cache: 'no-cache',
headers: { 'Content-Type': 'multipart/form-data' },
redirect: 'follow',
referrerPolicy: 'no-referrer'
};
const response = await axios.post(
'https://myhost.com:5000/api/addfileclass',
formData,
requestOptions )
const responseData = await response.data;
storeCredentials( responseData.credentials );
setShowAddFileClassForm(false);
}
The Console logs displayed are as below
FileClass.js:143 type of uploadfiles => object
FileClass.js:146 file, [object Object]
FileClass.js:151 onSave [{…}]0: {file: File, data: "data:application/vnd.openxmlformats-officedocument…jUHJvcHMvYXBwLnhtbFBLBQYAAAAAEgASANcEAADDUgAAAAA="}length: 1__proto__: Array(0)
FileClass.js:152 save new file class FormData {}
The log on line 151 confirms that the uploadFiles has an array of Files
However when I append to FormData 'files' it is changed as [Object Object]
Due to this on the flask backend I am not getting any values in request.files and I get the following error
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ubuntu/.local/lib/python3.8/site-packages/flask_cors/decorator.py", line 128, in wrapped_function
resp = make_response(f(*args, **kwargs))
File "/home/ubuntu/platform-streamxls/react-excel-upload/flaskapp/routes.py", line 286, in addfileclass
downloadfile = request.files["file"]
File "/home/ubuntu/.local/lib/python3.8/site-packages/werkzeug/datastructures.py", line 442, in __getitem__
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'file'
The python code segment where the error is raised is
def addfileclass():
headers = request.headers
downloadfile = request.files["file"]
Any help on how to fix the react will be nice
The variable uploadFiles is an object array which has a structure of data,files
uploadFiles = []{ data : "mime information", file : "the file Object"}
I changed the append statement to the following
const formData = new FormData();
formData.append("file", uploadFiles[0].file);
This works fine for a single file
I have worked out the pattern to upload multiple files.
most of the examples I searched had multiple api calls in a loop to upload multiple files; this is not always an efficient solution
I have the following for multiple files
const formData = new FormData();
uploadFiles.map((file, idx) => {
formData.append("file"+idx, file.file);
});
formData.append("data", JSON.stringify({ filecount: uploadFiles.length }));
In my backend - I use the filecount to identify the number of files that are there and use the values of "file0", "file1"... to handle the file uploads
I am creating a system consisting angularjs frontend web app and DRF rest interface.
I can use command line 'curl' to upload image file to DRF rest interface, but when I use angularjs http post, I got the error message: 'OrderedDict' object has no attribute 'pk'
My DRF setup is as follows:
models.py:
def upload_to(instance, filename):
return 'post_image/{0}/{1}'.format(instance.author.id, filename)
class PostImage(models.Model):
author = models.ForeignKey(Author, blank=False, editable=False, related_name='images')
post = models.ForeignKey(Post, blank=False, editable=False, related_name='images')
image = models.ImageField(_('image'), blank=True, null=True, upload_to=upload_to)
created = models.DateTimeField(editable=False)
updated = models.DateTimeField(editable=False)
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
self.updated = timezone.now()
return super(PostImage, self).save(*args, **kwargs)
serializers.py
class PostImageSerializer(serializers.HyperlinkedModelSerializer):
author = serializers.HyperlinkedRelatedField(read_only=True, view_name='author-detail')
post = serializers.HyperlinkedRelatedField(read_only=True, view_name='post-detail')
class Meta:
model = PostImage
fields = ('url', 'image', 'author', 'post', 'created', 'updated')
views.py
class PostImageView(generics.ListCreateAPIView):
"""
List and Create post image endpoint
Allowed request method: Get, Post
"""
serializer_class = PostImageSerializer
permission_classes = [permissions.IsAuthenticated]
parser_classes = (FormParser, MultiPartParser, FileUploadParser,)
def get_queryset(self):
queryset = super(PostImageView, self).get_queryset()
return queryset.filter(post__pk=self.kwargs['pk'])
def perform_create(self, serializer):
post = Post.objects.get(pk=self.kwargs['pk'])
if 'upload' in self.request.data:
file_obj = self.request.data['upload']
serializer.save(author=self.request.user, post=post, image=file_obj)
return Response(status=status.HTTP_201_CREATED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
I am using JWT authentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
) ,
}
Log error message:
Internal Server Error: /api/v1/post/22/image
Traceback (most recent call last):
File "/root/rest_drf/env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/views.py", line 452, in dispatch
response = self.handle_exception(exc)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/views.py", line 449, in dispatch
response = handler(request, *args, **kwargs)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/generics.py", line 244, in post
return self.create(request, *args, **kwargs)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/mixins.py", line 21, in create
headers = self.get_success_headers(serializer.data)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 466, in data
ret = super(Serializer, self).data
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 215, in data
self._data = self.to_representation(self.validated_data)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 435, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/relations.py", line 264, in to_representation
return self.get_url(value, self.view_name, request, format)
File "/root/rest_drf/env/local/lib/python2.7/site-packages/rest_framework/relations.py", line 199, in get_url
if obj.pk is None:
AttributeError: 'OrderedDict' object has no attribute 'pk'
[pid: 29484|app: 0|req: 2/4] 76.114.185.25 () {54 vars in 1242 bytes} [Sun Jan 24 16:41:13 2016] POST /api/v1/post/22/image => generated 107983 bytes in 153 msecs (HTTP/1.1 500) 2 headers in 92 bytes (1 switches on core 1)
I am trying to post a csv file from my client to my server and load the file into pandas. I get the error IOError: Expected file path name or file-like object, got type
I tried sending the same file to the same url through postman and there was no error. So I think there is a problem with how angular sends the file or how it is appended to FormData.
app.py
from flask import Flask, render_template, request, send_from_directory
from minimongo import Model, configure
import pandas
import csv
app = Flask(__name__)
configure(host="xx.xx.com", port=xx, username="xx", password="xx")
class Placement(Model):
class Meta:
database= "flask_api"
collection = "placements"
#app.route('/')
def index():
return render_template("index.html")
#app.route('/<path:path>')
def send_static(path):
return send_from_directory('static', path)
#app.route('/receive_form', methods=['GET', 'POST'])
def receive_form():
instance = Placement()
instance.x = "test"
instance.save()
df = pandas.read_csv(request.files.get("csv"))
return "200"
if __name__ == '__main__':
app.run(debug=True)
app.js
angular.module("negatizer", ['ngRoute'])
.service("getJson", function($http){
this.getJson = function(callback){
$http.get("/mock/data.json").then(callback)
}
})
.service("postFormData", function($http){
this.postFormData = function(data, callback){
console.log("service")
$http.post("/receive_form", data).then(callback)
}
})
.controller("mainCtrl", function($scope, $window, getJson, postFormData){
$scope.fileChanged = function(element) {
var form = new FormData()
form.append("csv", element.files[0])
postFormData.postFormData(form, function() {
console.log("I sent the the form")
})
}
getJson.getJson(function(response) {
console.log(response.data)
$scope.varName = response.data
})
})
.config(function ($routeProvider) {
$routeProvider
.when("/", {
controller: "mainCtrl",
templateUrl: "partials/home.html"
})
.otherwise({
redirectTo: "/mock/data.json"
});
});
the form in index.html
<form action="/" enctype="multipart/form-data" id="form" method="post">
<span id="upload">
Upload Automatic Placements<input ng-model="photo" onchange="angular.element(this).scope().fileChanged(this)" type="file" name="csv">
</span>
</form>
traceback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/student/Documents/flask_projects/neg_app/app.py", line 28, in receive_form
df = pandas.read_csv(request.form.get("csv"))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.py", line 498, in parser_f
return _read(filepath_or_buffer, kwds)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.py", line 275, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.py", line 590, in __init__
self._make_engine(self.engine)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.py", line 731, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/io/parsers.py", line 1103, in __init__
self._reader = _parser.TextReader(src, **kwds)
File "pandas/parser.pyx", line 353, in pandas.parser.TextReader.__cinit__ (pandas/parser.c:3246)
File "pandas/parser.pyx", line 608, in pandas.parser.TextReader._setup_parser_source (pandas/parser.c:6288)
IOError: Expected file path name or file-like object, got <type 'NoneType'> type
I am trying out webapp2 on app engine, and getting following error when I am trying to test it at route, http://localhost:8080/products/2. I should probably mention that the other 2 routes that you can see below ('/' & '/products') work just fine.
Traceback (most recent call last):
File "/home/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/home/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/home/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/home/harshal/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/home/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/home/Downloads/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
TypeError: get() got an unexpected keyword argument 'product_id'
INFO 2013-12-31 17:36:55,084 module.py:617] default: "GET /products/2 HTTP/1.1" 500 228
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')
application = webapp2.WSGIApplication([
webapp2.Route(r'/', handler=MainPage, name='home'),
webapp2.Route(r'/products', handler=MainPage, name='product-list'),
webapp2.Route(r'/products/<product_id:\d+>', handler=MainPage, name='product'),
])
You've included a capture-group in your 'product' route, but haven't defined the corresponding keyword-argument in your handler function. Your handler class should look something like:
class MainPage(webapp2.RequestHandler):
def get(self, product_id=None):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')