I try to implement a view based on BaseDeleteView for a website that acts as a frontend to an REST backend. Both sides communicate over HTTP requests. What I want to achieve is that I send a GET request to an activation URI (send per email after registration). Inside this view I first send a HTTP request to a backend, and then delete the activation object from the database of the frontend. I don't want to have a confirmation page, so DeleteView is not possible.
class ActivationView(BaseDeleteView):
success_url = "/activation/success/"
def get_object(self, queryset=None):
uuid = self.kwargs['uuid']
try:
obj = AccountRegistration.objects.get(uuid=uuid)
except ObjectDoesNotExist:
raise Http404('Registration not found.')
return obj
def delete(self, request, *args, **kwargs):
obj = self.get_obj()
if obj.expire_date < datetime.now():
obj.delete()
raise Http404('Registration expired.')
# send a http request to the backend
t = Transaction('/activate/%s/' % obj.account_name)
t.emit()
# delete the object
obj.delete()
# and redirect the request
return HttpResponseRedirect(self.get_success_url())
My urls.py looks like that:
url(r'^activate/(?P<uuid>\w+)/$',
ActivationView.as_view(), name="account-activate"),
But I get the following error:
Traceback (most recent call last):
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__
return self.application(environ, start_response)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 272, in __call__
response = self.get_response(request)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/core/handlers/base.py", line 169, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/core/handlers/base.py", line 203, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/views/generic/base.py", line 47, in view
return self.dispatch(request, *args, **kwargs)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in dispatch
return handler(request, *args, **kwargs)
File "/home/crito/.pythonbrew/venvs/Python-2.7.2/thirty-web/lib/python2.7/site-packages/django/views/generic/detail.py", line 100, in get
return self.render_to_response(context)
AttributeError: 'ActivationView' object has no attribute 'render_to_response'
In my eyes it shouldn't even call render_to_response. Any ideas?
If you want to leave out the confirmation page, just call your DeleteView directly with POST. This is most desirable as the deletion of an object should be protected by csrf.
You've inherited from BaseDeleteView, which as the documentation states, doesn't include the TemplateResponseMixin - ie all the bits that are to do with rendering a response.
Inherit from DeleteView instead.
Related
So I´ve tried to make an ajax for my models but it is giving me a matching query does not exist, here is the full error:
Internal Server Error: /messages/notification/
Traceback (most recent call last):
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\generic\detail.py", line 106, in get
self.object = self.get_object()
File "C:\Users\berna\Desktop\Python & Javascript\Web development\MiFamiliaEsUnDesastre\mifamiliaesundesastre\chat\views.py", line 26, in get_object
obj, created = Thread.objects.get_or_new(self.request.user, other_username)
File "C:\Users\berna\Desktop\Python & Javascript\Web development\MiFamiliaEsUnDesastre\mifamiliaesundesastre\chat\models.py", line 29, in get_or_new
user2 = Klass.objects.get(username=other_username)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\berna\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\query.py", line 415, in get
raise self.model.DoesNotExist(
django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.
HTTP GET /messages/notification/ 500 [0.16, 127.0.0.1:56012]
Also here is my code:
models.py
class ProfileImage(models.Model):
"""
Profile model
"""
user = models.OneToOneField(
verbose_name=_('User'),
#to=settings.AUTH_USER_MODEL,
to = User,
related_name='profile',
on_delete=models.CASCADE
)
avatar = models.ImageField(upload_to='profile_image')
notifications = models.FloatField(default='0')
views.py
def notifications(request, user_id, *args, **kwargs):
user = User.objects.get(pk=user_id)
user.profile.notifications = user.profile.notifications + 1
user.save()
return JsonResponse(data=user.profile.notifications, safe=False)
urls.py
path('messages/notification/', notifications)
my html for the ajax call
// Add the notification val
$.get('notification/')
someone tell me that is that I dont have users, but when I do have a user, I dont know what is going on
You need to send user_id to the view:
path('messages/notification/(?P<user_id>[a-zA-Z0-9/_\.-]*)', notifications)
and:
$.get('messages/notification/{{ user.pk }}')
Update
You have to know their user id to get their notifications:
$.get('messages/notification/12234')
I assume you have a User model somewhere?
Also, user_id is coming in as a string, so need to int() that:
user = User.objects.get(pk=int(user_id))
Or use:
path('messages/notification/<int:user_id>', notifications)
So for does who saw this later, what I did is to change the
path('messages/notification/', notifications)
To
url(r'^ajax/notification/$', notification),
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'],
)
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.
I have created a class based view
class MyLibrary(generic.DetailView):
context_object_name = 'data'
def get_template_names(self):
request = self.request
template_name = 'my_library.html'
return [template_name]
def get_queryset(self):
request = self.request
user = request.user
context = {}
mainData = []
userIssuedBooks = BooksIssued.objects.filter(user=user)
print(userIssuedBooks)
if user.is_authenticated():
context['issuedBooks'] = userIssuedBooks
return context
I am getting following error when the view is getting called
Internal Server Error: /mylibrary/1/admin
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 149,
in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python34\lib\site-packages\django\contrib\auth\decorators.py", line 2
3, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\generic\base.py", line 88, in
dispatch
return handler(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\generic\detail.py", line 117,
in get
self.object = self.get_object()
File "C:\Python34\lib\site-packages\django\views\generic\detail.py", line 38,
in get_object
queryset = queryset.filter(pk=pk)
AttributeError: 'dict' object has no attribute 'filter'
I have no clue why this error is getting generated. Can someone help to find what is wrong here?
In django DetailView, get_queryset expects user to return a queryset(as the name implies) but you returned a dict context. You need to do your current stuff in get_context_data instead.
Django doc about adding extra context.
Am trying to build a permission class for my django rest framework view, which should either allow or disallow the user access.
class UserPermissions(permissions.DjangoModelPermissions):
"""
"""
def has_object_permission(self, request, view, obj):
# if safe methods (get, retrieve) we check permissions from django perms
if request.method in permissions.SAFE_METHODS:
return super(UserPermissions, self).has_object_permission(request, view, obj)
# else if methods (post, put, patch), we match user with obj and if obj is owner we grant him access
return request.user == obj
the above code seems to be working fine, but while I was build test cases. I built one case where I try to intentionally update user x using user y credentials
def test_patching_someones_else_profile(self):
""" Test patching someone's else profile """
response = self.c.post("/api/account/api-token-auth/", {'username': 'lion', 'password': 'password'})
self.assertEqual(response.status_code, 200, "User couldn't log in")
token = response.data['token']
user_id = response.data['id']
header = {'HTTP_AUTHORIZATION': 'Token {}'.format(token)}
response = self.c.patch(reverse('user-detail', args=['1', ]), {'last_name': 'mooz'}, **header)
the problem am seeing now, its suddenly throws an exception PermissionDenied(), it does not return any status_code to handle, instead the application is crashing with following exception
======================================================================
ERROR: test_patching_someones_else_profile (dlap.apps.account.tests.UserTestCase)
Test patching someone's else profile
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/mo/Projects/pythonic/dl-env/dlap/apps/account/tests.py", line 217, in test_patching_someones_else_profile
response = self.c.patch(reverse('user-detail', args=['1', ]), {'last_name': 'mooz'}, **header)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/test.py", line 84, in patch
return self.generic('PATCH', path, data, content_type, **extra)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/compat.py", line 487, in generic
return self.request(**r)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/test.py", line 143, in request
return super(APIClient, self).request(**kwargs)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/test.py", line 95, in request
request = super(APIRequestFactory, self).request(**kwargs)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/django/test/client.py", line 444, in request
six.reraise(*exc_info)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/django/core/handlers/base.py", line 139, in get_response
response = response.render()
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/response.py", line 59, in rendered_content
ret = renderer.render(self.data, media_type, context)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/renderers.py", line 577, in render
context = self.get_context(data, accepted_media_type, renderer_context)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/renderers.py", line 537, in get_context
raw_data_put_form = self.get_raw_data_form(view, 'PUT', request)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/renderers.py", line 475, in get_raw_data_form
serializer = view.get_serializer(instance=obj)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/generics.py", line 99, in get_serializer
serializer_class = self.get_serializer_class()
File "/Users/mo/Projects/pythonic/dl-env/dlap/apps/account/views.py", line 96, in get_serializer_class
obj = self.get_object()
File "/Users/mo/Projects/pythonic/dl-env/dlap/apps/account/views.py", line 107, in get_object
return super(UserViewSet, self).get_object(queryset=queryset)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/generics.py", line 321, in get_object
self.check_object_permissions(self.request, obj)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/views.py", line 284, in check_object_permissions
self.permission_denied(request)
File "/Users/mo/Projects/pythonic/dl-env/lib/python2.7/site-packages/rest_framework/views.py", line 135, in permission_denied
raise exceptions.PermissionDenied()
PermissionDenied
Any one faced this issue before? is there a way to return 403 with permission denied message without the app crashing?
Update:
As suggested below that get_seralizer_class() could be causing the problem, it is highly the reason why am facing this error. But, what alternatives do I have to build a dynamic seralizer class method similar to the below?
def get_serializer_class(self):
# decide on which seralizer to use
if u'create_guest' in self.action_map.itervalues():
return UserGuestSerializer
if u'create_user' in self.action_map.itervalues():
return PublicUserSerializer
obj = self.get_object()
if self.request.user.id == obj.id:
if u'set_password' in self.action_map.itervalues():
return PasswordSerializer
return PrivateUserSerializer
return PublicUserSerializer
You appear to be using a custom .get_serializer_class() method that is calling .get_object() for some reason.
File "/Users/mo/Projects/pythonic/dl-env/dlap/apps/account/views.py", line 96, in get_serializer_class
obj = self.get_object()
This is causing the per-object permission checks to be re-run when the Browsable API response is being rendered. Is it possible to reconsider your get_serializer_class implementation?
Edit: Note that you can probably simply inspect self.kargs['pk'] rather than actually calling through to get_object. It doesn't look like you need to perform the full object retrieval in order to make the ownership check.