Django Ajax Form Upload with Image - django

I am using Django + Ajax, and i'm trying to send a POST request to upload a form with an image.
However, i still get an error KeyError: 'file'
HTML form (notice i've added enctype="multipart/form-data"):
<form id="addProduct" method="post" enctype="multipart/form-data">
<label class="form-label required-field" for="file">Image</label>
<input class='form-control' id='file' name="file" type="file" accept="image/*" required/>
</form>
Javascript using AJAX requests:
$("#addProduct").on("submit", function (e) {
e.preventDefault()
var data = new FormData(this);
$.ajax({
url: '/admin/product/add/',
data: data,
type: 'post',
success: function (response) {
var result = response.result
console.log(result)
if (result == false) {
alert("Add product failed")
}
else {
alert("Add product successfully")
}
},
cache: false,
contentType: false,
processData: false
})
}
Django View - views.py:
class ProductAddPage(View):
def post(self, request):
img = request.FILES['file']
try:
#further processing
except:
traceback.print_exc()
return JsonResponse({"result":False}, status=200, safe=False)
return JsonResponse({"result":True}, status=200, safe=False)
Traceback:
Internal Server Error: /admin/product/add/
Traceback (most recent call last):
File "D:\Codes\Django\env\lib\site-packages\django\utils\datastructures.py", line 84, in __getitem__
list_ = super().__getitem__(key)
KeyError: 'file'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\Codes\Django\env\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "D:\Codes\Django\env\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Codes\Django\env\lib\site-packages\django\views\generic\base.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "D:\Codes\Django\env\lib\site-packages\django\contrib\auth\mixins.py", line 73, in dispatch
return super().dispatch(request, *args, **kwargs)
File "D:\Codes\Django\env\lib\site-packages\django\views\generic\base.py", line 142, in dispatch
return handler(request, *args, **kwargs)
File "D:\Codes\Django\draft\admin\views.py", line 346, in post
img = request.FILES['file']
File "D:\Codes\Django\env\lib\site-packages\django\utils\datastructures.py", line 86, in __getitem__
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'file'

Related

Django StreamingHttpResponse returns only a single yield result from generator to stream

I am trying to stream several large json files to the front end at a time (I need to stream all of them one by one, and can't split it into several requests):
def stream_response_generator(response):
yield json.dumps({ 'searchedVariants': response['searchedVariants']})
yield json.dumps({ 'genesById': response['genesById']})
yield json.dumps({ 'locusListsByGuid': response['locusListsByGuid']})
yield json.dumps({ 'genesQcData': response['genesQcData']})
#login_required(login_url=API_LOGIN_REQUIRED_URL)
#csrf_exempt
#log_request(name='query_variants_handler')
def query_variants_handler(request, search_hash):
...
return StreamingHttpResponse(stream_response_generator(response), content_type='application/octet-stream')
Only the very first searchedVariants response is streaming to the front end but other 3 are omitted. I verified it printing out the response on the frontend:
fetch(url, {
method: 'POST',
credentials: 'include',
body: JSON.stringify(search),
signal: signal,
}).then((response) => {
const reader = response.body.getReader()
let decoder = new TextDecoder('utf8');
let read
reader.read().then(read = (result) => {
if (result.done) return
let chunk = decoder.decode(result.value);
console.log(chunk)
reader.read().then(read)
})
})
In some tutorials, e.g.
https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/
Its written that we should pass a function generator instead of calling a function like I do, however, when I do that:
def stream_response_generator(response):
def generator():
yield json.dumps({ 'searchedVariants': response['searchedVariants']})
yield json.dumps({ 'genesById': response['genesById']})
yield json.dumps({ 'locusListsByGuid': response['locusListsByGuid']})
yield json.dumps({ 'genesQcData': response['genesQcData']})
return generator
#login_required(login_url=API_LOGIN_REQUIRED_URL)
#csrf_exempt
#log_request(name='query_variants_handler')
def query_variants_handler(request, search_hash):
...
return StreamingHttpResponse(stream_response_generator(response), content_type='application/octet-stream')
I am getting an error:
2022-10-21 03:34:28,165 ERROR: Traceback (most recent call last):
File "/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/gris/decorators.py", line 26, in wrapper
return f(request, *args, **kwargs)
File "/variant_search_api.py", line 141, in query_variants_handler
return StreamingHttpResponse(stream_response_generator(response), content_type='application/octet-stream')
File "/python3.6/site-packages/django/http/response.py", line 367, in __init__
self.streaming_content = streaming_content
File "/python3.6/site-packages/django/http/response.py", line 382, in streaming_content
self._set_streaming_content(value)
File "/python3.6/site-packages/django/http/response.py", line 386, in _set_streaming_content
self._iterator = iter(value)
TypeError: 'function' object is not iterable
I suspect it is somehow related to #csrf_exempt decorator but not sure. So, why does StreamingHttpResponse not stream other values? How to fix it?

AttributeError: x object has no attribute 'GET' (DRF)

I am trying to grab a user's list using Django Rest Framework and an Ajax request. However, I get the following error
AttributeError: 'UserListViewSet' object has no attribute 'GET'
Not sure what I am doing wrong - I am newer to DRF than vanilla Django.
Ajax call:
const showUserLists = function(map){
let userName = "Henry";
$.ajax({
type: 'GET',
url: '/api/userlist/',
data: {
'username': userName
},
success: function (data) {
data.forEach(item => {
console.log(item.list_name)
$("#userLists").append("<li class=userlist data-name=\"" + item.list_name + "\">" + item.list_name + "</li>")
})
}
});
};
urls.py:
router = DefaultRouter()
router.register('userlist', views.UserListViewSet, basename= 'userlist')
router.register('uservenue', views.UserVenueViewSet, basename= 'uservenue')
views.py
#this shows all lists for a user
class UserListViewSet(viewsets.ModelViewSet):
serializer_class = UserListSerializer
def get_queryset(request):
name = request.GET.get('username', None)
return UserList.objects.filter(user=name)
Traceback:
Traceback (most recent call last):
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 38, in list
queryset = self.filter_queryset(self.get_queryset())
File "/Users/x/Desktop/Coding/anybody/anybody1/api/views.py", line 33, in get_queryset
name = request.GET.get('username', None)
AttributeError: 'UserListViewSet' object has no attribute 'GET'
The first parameter of get_queryset is not a request, but the UserListViewSet, so the self, you can obtain the request with self.request:
class UserListViewSet(viewsets.ModelViewSet):
serializer_class = UserListSerializer
def get_queryset(self):
name = self.request.GET.get('username', None)
return UserList.objects.filter(user=name)

Django getting (AttributeError: 'str' object has no attribute 'get') after submitting a form

I am studying django recently, and I met problem,
Internal Server Error: /event_edit
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/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.7/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.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/workspace/CalendarProject/cencal/views.py", line 107, in event_edit
if form.is_valid():
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 185, in is_valid
return self.is_bound and not self.errors
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 180, in errors
self.full_clean()
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 381, in full_clean
self._clean_fields()
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 393, in _clean_fields
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
File "/usr/local/lib/python3.7/site-packages/django/forms/widgets.py", line 258, in value_from_datadict
return data.get(name)
AttributeError: 'str' object has no attribute 'get'
This error message appeared while doing form.is_valid(), but I can't know what is the problem. There was surely no problem with form field values.
If you need any additional informations for this, I am ready to do it.
event_edit view
def event_edit(request, pk=None):
pk2=0
if pk==None:
if request.method == "POST":
pk2 = int(request.POST.get('pk', None))
else:
pk2 = int(request.GET.get('pk', None))
else:
pk2 = pk
event = get_object_or_404(Event, pk=pk2)
if request.method == "POST":
form = EventForm(request.POST.get('form'))
if form.is_valid():
event = form.save(commit=False)
event.author = request.user
event.save()
jsonres = JsonResponse({"res": "successful"})
jsonres.status_code = 200
return jsonres
# return render(request, 'cencal/index.html', {'sidebarContent':render_to_string('cencal/detailevent.html', {'event': event})})
# return redirect('detailevent', pk=event.pk)
else:
print(form.errors.as_json())
jsonres = JsonResponse({"error": form.errors.as_json()})
jsonres.status_code = 599
return jsonres
else:
print("else")
form = EventForm(instance=event)
return render(request, 'cencal/eventform.html', {'form':form, 'edit':"true", 'pk':pk2})
template javascript function to submit form
function makeEvent(event){
event.preventDefault();
var year = event.target.querySelector("#id_date").value.slice(0,4);
var month = event.target.querySelector("#id_date").value.slice(5,7);
var day = event.target.querySelector("#id_date").value.slice(8,10);
var form = $("#eventform");
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: {'form' : form.serialize(), 'pk' : form.attr("pk"), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function(response){
console.log("makeEvent() successful");
console.log(response);
refreshCalendarAjax(year, month);
listevent(year, month, day);
//아래 메시지 make/edit별로 따로 출력해야 함.
document.getElementById("sidebar").insertAdjacentHTML( 'afterbegin', '<div class="info">일정 등록 성공!</div>' );
},
error: function(data){
if (data.status == 599) {
listevent(year, month, day);
errors = JSON.parse(data.responseJSON.error);
errors['__all__'].forEach(function(error){
document.getElementById("sidebar").insertAdjacentHTML( 'afterbegin', error['message'] );
})
} else {
alert("code:"+data.status+"\n"+"message:"+data.status+"\n"+"error:"+data.error);
}
},
});
}
A Django form requires a dictionary-like object as data, like request.GET and request.POST, not a string. Normally therefore you construct a form with:
form = EventForm(request.POST, request.FILES)
Since a HTTP request is basically text, request.POST['form'] will always be a string, not a dictionary, not even if you pass a JSON encoded blob to the the form key.
In case you serialize this, you need to de-serialize it, for example with:
from django.http import QueryDict
# …
form = EventForm(QueryDict(request.POST['form']))

Attribute error 'QueryDict' object has no attribute '_meta'

I'm trying to send a post request from PostMan into my Django view and I'm getting this error. "AttributeError: 'QueryDict' object has no attribute '_meta'"
From what I've gathered it has something to do with the form.save() as seen in traceba
I've searched all over to find a solution or even a better way to achieve an image post from a external web client to a Django server.
All help is very much appreciated.
Traceback
Capture.PNG
form is valid
Internal Server Error: /getimg/
Traceback (most recent call last):
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\decorators.py", line 50, in handler
return func(*args, **kwargs)
File "C:\Users\Gedit\Desktop\django\indivproj\getimg\api\views.py", line 21, in getimg
form.save()
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\serializers.py", line 207, in save
self.instance = self.update(self.instance, validated_data)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\serializers.py", line 979, in update
info = model_meta.get_field_info(instance)
File "C:\Users\Gedit\Desktop\django\virtualenv\lib\site-packages\rest_framework\utils\model_meta.py", line 35, in get_field_info
opts = model._meta.concrete_model._meta
AttributeError: 'QueryDict' object has no attribute '_meta'
[24/Mar/2020 13:39:25] "POST /getimg/ HTTP/1.1" 500 20251
Views.py
#api_view(['POST',])
def getimg(request):
if request.method == 'POST':
form = ImageSerializer(request.POST, request.FILES)
logger.warning(request.FILES['img'])
if form.is_valid():
#raise_exception=True
logger.warning('form is valid')
form.save()
logger.warning()
response_dict = {'post': 'success'}
return HttpResponse(simplejson.dumps(response_dict), content_type='application/javascript')
else:
logger.warning(form.errors)
else:
form = ImageSerializer()
return render(request, 'getimg.html', {'form': form})
Serializers.py
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = Image
fields = '__all__'
Models.py
class Image(models.Model):
# name = models.CharField(default='name', max_length=30)
img = models.ImageField(upload_to='images/', max_length=1000)
Urls.py
app_name = 'getimg'
urlpatterns = [
# ex: /polls/
path('', views.getimg, name='getimg'),
path('gettext/', views.gettext, name='gettext'),
path('success', views.success, name = 'success'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Postman
so after looking around as a smart individual I realized i have not defined what save() function is... so now i do
The code that fixed the error but still not working
def save(self):
img = Image(
img =self.validated_data['img'],
)

AttributeError: 'bytes' object has no attribute

I have a class in which I am checking user permissions, and depending on them, I return a list of results from models. Here is what I have:
from AnnualLeave.models import Leaves, RejectedLeaves, Employee
class GetLeaves:
def get_results(request):
try:
if request.user.groups.filter(name__in=['SuperAdmin']).exists():
return Leaves.objects.all()
elif request.user.groups.filter(name__in=['Admin']).exists():
return Leaves.objects.filter(employee_id=Employee.objects.get(manager_id=request.user.pk))
else:
messages.error(request, "You are not allowed on this page")
return render(request, 'users/home.html')
except (Leaves.DoesNotExist, Employee.DoesNotExist):
return []
def process_results(request):
leave_request = []
for leave in GetLeaves.get_results(request):
content = {'emp_id': leave.employee_id,
'emp_name': Employee.objects.get(user_id=leave.employee_id).user.get_full_name(),
'start_date': leave.start_date,
'end_date': leave.end_date,
'reason': leave.get_reason_display(),
'description': leave.description,
}
....
leave_request.append(content)
return leave_request
And then I'm calling process_results function in TemplateView like this:
class ProcessLeaveRequest(TemplateView):
template_name = 'LMSAdmin/process_leave_request.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'leave_requests': GetLeaves.process_results(request)})
Here is a traceback of error:
Internal Server Error: /lms_admin/upcomingleaves/
Traceback (most recent call last):
File "C:\Program Files (x86)\Python37-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "D:\Projects\LMS\LMSAdmin\views.py", line 77, in get
for leave in GetLeaves.process_results(request):
File "D:\Projects\LMS\LMSAdmin\views.py", line 39, in process_results
content = {'emp_id': leave.employee_id,
AttributeError: 'bytes' object has no attribute 'employee_id'
From what I can see, it is reading the entire webpage with the request parameter in functions. Like the get_results function is not returning a list, but the entire webpage. I do not understand why this is happening because it was working fine before without any changes.
You should not return a HttpRequest from get_results. Instead raise a PermissionDenied error.
else:
from django.core.exceptions import PermissionDenied
messages.error(request, "You are not allowed on this page")
raise PermissionDenied
If you want to redirect to a different page, handle that in the view. You can capture the PermissionDenied and return the redirect.