I am getting this problem, any help will be appreciated, Im getting an arror trying to sign-in or sign-up.Error bellow. AttributeError at /sign-up 'WSGIRequest' object has no attribute 'is_ajax' I know that function is depreciated now, but i can't seem to fix the issue.
mixins.py
class AjaxFormMixin(object):
'''
Mixin to ajaxify django form - can be over written in view by calling form_valid method
'''
def form_invalid(self, form):
response = super(AjaxFormMixin, self).form_invalid(form)
if self.request.is_ajax():
message = FormErrors(form)
return JsonResponse({'result': 'Error', 'message': message})
return response
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if self.request.is_ajax():
form.save()
return JsonResponse({'result': 'Success', 'message': ""})
return response
views.py
def profile_view(request):
'''
function view to allow users to update their profile
'''
user = request.user
up = user.userprofile
form = UserProfileForm(instance=up)
if request.is_ajax():
form = UserProfileForm(data=request.POST, instance=up)
if form.is_valid():
obj = form.save()
obj.has_profile = True
obj.save()
result = "Success"
message = "Your profile has been updated"
else:
message = FormErrors(form)
data = {'result': result, 'message': message}
return JsonResponse(data)
else:
context = {'form': form}
context['google_api_key'] = settings.GOOGLE_API_KEY
context['base_country'] = settings.BASE_COUNTRY
return render(request, 'users/profile.html', context)
class SignUpView(AjaxFormMixin, FormView):
'''
Generic FormView with our mixin for user sign-up with reCAPTURE security
'''
template_name = "users/sign_up.html"
form_class = UserForm
success_url = "/"
# reCAPTURE key required in context
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["recaptcha_site_key"] = settings.RECAPTCHA_PUBLIC_KEY
return context
# over write the mixin logic to get, check and save reCAPTURE score
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if self.request.is_ajax():
token = form.cleaned_data.get('token')
captcha = reCAPTCHAValidation(token)
if captcha["success"]:
obj = form.save()
obj.email = obj.username
obj.save()
up = obj.userprofile
up.captcha_score = float(captcha["score"])
up.save()
login(self.request, obj,
backend='django.contrib.auth.backends.ModelBackend')
# change result & message on success
result = "Success"
message = "Thank you for signing up"
data = {'result': result, 'message': message}
return JsonResponse(data)
return response
class SignInView(AjaxFormMixin, FormView):
'''
Generic FormView with our mixin for user sign-in
'''
template_name = "users/sign_in.html"
form_class = AuthForm
success_url = "/"
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if self.request.is_ajax():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
# attempt to authenticate user
user = authenticate(
self.request, username=username, password=password)
if user is not None:
login(self.request, user,
backend='django.contrib.auth.backends.ModelBackend')
result = "Success"
message = 'You are now logged in'
else:
message = FormErrors(form)
data = {'result': result, 'message': message}
return JsonResponse(data)
return response
CodePudding user response:
Use it like if request.headers.get('x-requested-with') == 'XMLHttpRequest':
everywhere so:
def profile_view(request):
'''
function view to allow users to update their profile
'''
user = request.user
up = user.userprofile
form = UserProfileForm(instance=up)
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
form = UserProfileForm(data=request.POST, instance=up)
if form.is_valid():
obj = form.save()
obj.has_profile = True
obj.save()
result = "Success"
message = "Your profile has been updated"
else:
message = FormErrors(form)
data = {'result': result, 'message': message}
return JsonResponse(data)
else:
context = {'form': form}
context['google_api_key'] = settings.GOOGLE_API_KEY
context['base_country'] = settings.BASE_COUNTRY
return render(request, 'users/profile.html', context)
For class based views use it as if self.request.headers.get('x-requested-with') == 'XMLHttpRequest':
CodePudding user response:
As of django-3.1, the .is_ajax()
method [Django-doc] was deprecated. Indeed, in the release notes, we see:
The
HttpRequest.is_ajax()
method is deprecated as it relied on a jQuery-specific way of signifying AJAX calls, while current usage tends to use the JavaScript Fetch API. Depending on your use case, you can either write your own AJAX detection method, or use the newHttpRequest.accepts()
method if your code depends on the client Accept HTTP header.
Originally, it used:
def is_ajax(): return request.headers.get('x-requested-with') == 'XMLHttpRequest'
But note that this is, and has always been something specific to jQuery, and therefore it makes not much sense: a browser or HTTP library can always mimic this behavior, and you can make AJAX requests without this header, and thus it is not reliable.
You can check if the browser accepts json/xml with .accepts(…)
[Django-doc] which is probably what an AJAX request will try to accept, so:
self.request.accepts('application/json')
or:
self.request.accepts('application/xml')
are likely candidates for this.