local variable 'submission' referenced before assignment - django

I encounter this error for my django project. my app is called "scoresubmission"
basially i have a feature in the website to allow user download report.
So in my views.py file i have report function and import report.py file, where it shows how report is built
It shows the error happens in this line of code:
submission=Submission.objects.get(month=month,year=reportyear,program=program)
Views.py
def report(request):
from scoresubmission.report import reportA, reportB, reportC
reportType = request.POST["reportType"]
reportYear = int(request.POST["reportYear"])
if reportType == 'a':
report_content = reportA(reportYear)
response = HttpResponse(report_content, content_type="text/csv")
response['Content-Disposition'] = 'inline; filename=5SAuditYearlySummaryReport_%d.xlsx' %reportYear
report.py where it has the relevant code
for facility in facilities:
worksheet.write(row,col,facility.name,facility_format)
for i in range(12): # 12 months
month=i+1
programs=Program.objects.filter(facility_id=facility.id)
avg_totalscore=0
count=1
for program in programs:
print(program)
try:
submission=Submission.objects.get(month=month,year=reportyear,program=program)
print(submission)
avg_score=Result.objects.filter(submission=submission).aggregate(Avg('NewScore'))
#print avg_score.get('NewScore__avg')
avg_totalscore=(avg_totalscore + avg_score.get('NewScore__avg'))/count
count=count+1
except submission.DoesNotExist:
pass
#print avg_totalscore
if avg_totalscore!=0:
worksheet.write(row,i+3,avg_totalscore,red_format)
else:
worksheet.write(row,i+3,'-',red_format)
Traceback (most recent call last):
File "C:\Users\CHLOZHAO\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\CHLOZHAO\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\CHLOZHAO\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\CHLOZHAO\AppData\Local\Programs\Python\Python37\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\D Drive\5S Audit Website\my5saudit\scoresubmission\views.py", line 185, in report
report_content = reportA(reportYear)
File "C:\D Drive\5S Audit Website\my5saudit\scoresubmission\report.py", line 79, in reportA
except submission.DoesNotExist:
UnboundLocalError: local variable 'submission' referenced before assignment

In your except you need to refer to the class Submission, not the object, since it does not per se exists at that time:
try:
submission=Submission.objects.get(month=month,year=reportyear,program=program)
print(submission)
avg_score=Result.objects.filter(submission=submission).aggregate(Avg('NewScore'))
#print avg_score.get('NewScore__avg')
avg_totalscore=(avg_totalscore + avg_score.get('NewScore__avg'))/count
count=count+1
except Submission.DoesNotExist: # reference to the class, not the object
pass
If Sibmission.objects.get(..) fails, then the submission variable is never assigned, and hence submission.DoesNotExist makes no sense.
You acutally should never use the object, and always use the model class itself to refer to the DoesNotExist exception class.

Related

Duration matching query does not exist

Traceback (most recent call last):
File "/home/ahmed/SavannahX/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/ahmed/SavannahX/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ahmed/SavannahX/venv/lib/python3.9/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/ahmed/SavannahX/app/views.py", line 1352, in yearly_subscription_plans
duration = Duration.objects.get(name="yearly")
File "/home/ahmed/SavannahX/venv/lib/python3.9/site-packages/```
django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/ahmed/SavannahX/venv/lib/python3.9/site-packages/django/db/models/query.py", line 496, in get
raise self.model.DoesNotExist(
Exception Type: DoesNotExist at /yearly/subscriptions/
Exception Value: Duration matching query does not exist.
You are using the .get() function but it has not found a matching object. This is the danger of using get, it raises an exception if the object isn't found. The .filter() function by contrast will just return an empty queryset. You can either:
Use the get_object_or_404 function that returns a 404 HTTP response if the object is not found.
from django.shortcuts import get_object_or_404
duration = get_object_or_404(Duration, pk=pk)
or
Wrap the get() in a try/except wrapper:
try:
Duration.objects.get(name="yearly")
except:
# do something else, probably return 404...
duration = Duration.objects.get(name="yearly")
above code is giving the error as get method raises the "DoesNotExist" if the object is not found and can be handled as below ways
First method
Duration.objects.filter(name="yearly").first()
Second method
from django.shortcuts import get_object_or_404
duration = get_object_or_404(Duration, pk=pk)
Third method
try:
Duration.objects.get(name="yearly")
except:
#please handle the exception here

ValueError at /books/results/

"Field 'id' expected a number but got 'results'."
I'm getting this error while trying to use search filter over a list of books. It was working fine until I changed the Class-based view to Function based view.
This was the Class based view earlier using the default DetailView class:
class BookDetailView(LoginRequiredMixin,DetailView):
model = models.Book
template_name='book_detail.html'
login_url='login'
This is the new Function based detail view I changed to:
#login_required
def book_detail(request,book_id):
model =models.Book
book=model.objects.get(id=book_id)
template ='book_detail.html'
owner =CustomUser.objects.get(username=book.owner)
return render(request,template,{'book':book,'owner':owner})
Independently when I'm trying to go to detail view, its working fine. But when I try to search using the 'book_search' view, its throwing this error. Previously search functionality was also working fine.
#login_required
def book_search(request):
template ='book_list.html'
model =models.Book
query =request.GET.get('q')
results =model.objects.exclude(owner =request.user).order_by('-available','-id')
if query:
results =results.filter(Q(title__icontains =query))
paginator = Paginator(results, 9)
page =request.GET.get('page')
try:
books =paginator.page(page)
except PageNotAnInteger:
books =paginator.page(1)
except EmptyPage:
books= paginator.page(paginator.num_pages)
return render(request,template,{'books':books,'query':query,'page':page})
It has something to do with the result set that the search view is returning a list of books while detail view only require just one id.
Edit: Error stack:-
ValueError: invalid literal for int() with base 10: 'results'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Dell\Documents\read_bus\books\views.py", line 216, in book_detail
book=results.get(id=book_id)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 404, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 904, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 923, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1337, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1365, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1298, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1155, in build_lookup
lookup = lookup_class(lhs, rhs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\lookups.py", line 22, in __init__
self.rhs = self.get_prep_lookup()
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\lookups.py", line 72, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\fields\__init__.py", line 1772, in get_prep_value
) from e
For this detail_view:
URLs should look like:
urlpatterns =[
path('book/<int:pk>',views.book_detail,name ='book_detail'),
path('results/',views.book_search,name ='search'),
]
While the views function should be this:
#login_required
def book_detail(request,book_id):
model =models.Book
book=model.objects.get(id=book_id)
template ='book_detail.html'
owner =CustomUser.objects.get(username=book.owner)
return render(request,template,{'book':book,'owner':owner})
Passing value as http://127.0.0.1:8000/api/book/1
I seem to have found the solution.
It was actually the url pattern for the 'book_detail' that was causing the problem. I had created it without using path converter
urls.py:
...
urlpatterns =[
path('<book_id>/',views.book_detail,name ='book_detail'),
path('results/',views.book_search,name ='search'),
]
I thought just using <book_id> would suffice, and since it is higher in the hierarchy
of urlpatterns, it was matched for 'results' too.
Changing the path to <int:book_id> worked. Now I've realised the significance of the little path converter and won't ever forget using this.

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.

Test permission denied not catched

I try to check with unittests if it is possible to access a certain url without the proper permissions.
When I wrote the test everything worked correctly. I don't know if the error started to occurs after a Django update because I didn't check the test after the update and just started to write new tests which failed. So I checked my old test which is now failing too.
class MemberTestMethods(TestCase):
def setUp(self):
# Create user
user = User.objects.create_user('temp', 'temp#temp.tld', 'temppass')
user.first_name = 'temp_first'
user.last_name = 'temp_last'
user.save()
# login with user
self.client.login(username='temp', password='temppass')
# Create member
member = Member.objects.create(salutation=Member.MR, first_name='Temp', last_name='Temp')
member.save()
def test_member_list_permission(self):
"User should only access member list if view permission is set"
user = User.objects.get(username='temp')
response = self.client.get(reverse('members:list'))
self.assertEqual(response.status_code, 403)
user.user_permissions.add(Permission.objects.get(codename='view_member'))
response = self.client.get(reverse('members:list'))
self.assertEqual(response.status_code, 200)
After running python manage.py test I get the following error
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
WARNING:django.request:Forbidden (Permission denied): /de/reporting/
Traceback (most recent call last):
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 84, in dispatch
return self.handle_no_permission()
File "/home/***/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 43, in handle_no_permission
raise PermissionDenied(self.get_permission_denied_message())
django.core.exceptions.PermissionDenied
Previously the test ran successfully while checking for HTTP-Code 403 like it is describe in the documentation (https://docs.djangoproject.com/en/2.1/topics/testing/tools/#exceptions)
The full Sourceode is available at Github (https://github.com/HamburgerJungeJr/pyVerein/tree/pyReportJasper/pyVerein/members)
Am I missing a change in the Django-Test system?
I just found the solution. The PyReportJasper-package set the global logging level to INFO. After changing this the error is gone.

Django .get() returns a tuple and not the object

I have a simple function which looks like this:
parent_key = SeoKeys.objects.get(view_id=view_id, key_nbr=key_nbr)
if parent_key.status != 'active':
parent_key.status = status
parent_key.save()
metrics, created = SeoMetrics.objects.get_or_create(
seo_url = url_sent,
date = date,
parent_key = parent_key,
defaults = {
'parent_key':parent_key,
'seo_url': url_sent,
'url_found':url_found,
'position':position,
}
)
Now in theory this should work, however I get the following error:
ValueError: Cannot assign "(<SeoKeys: SeoKeys object>,)": "SeoMetrics.parent_key" must be a "SeoKeys" instance.
This happens because it's a tuple. If I do 'parent_key':parent_key[0] it will save it fine. However this seems a rather hacked solution and I would like to rather understand why this happens. Any ideas?
My model looks something like this:
class SeoMetrics(models.Model):
parent_key = models.ForeignKey('SeoKeys', on_delete=models.CASCADE)
Edit:
Added the full error:
Internal Server Error: /hook/
Traceback (most recent call last):
File "/Users/Costantin/GDrive/Analytic.me/dev/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/Costantin/GDrive/Analytic.me/dev/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/Costantin/GDrive/Analytic.me/dev/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/Costantin/GDrive/Analytic.me/dev/venv/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/Costantin/GDrive/Analytic.me/dev/backend/apps/seo_app/views.py", line 152, in webhook
metrics.parent_key = parent,
File "/Users/Costantin/GDrive/Analytic.me/dev/venv/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 216, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "(<SeoKeys: SeoKeys object>,)": "SeoMetrics.parent_key" must be a "SeoKeys" instance.
File "/Users/Costantin/GDrive/Analytic.me/dev/backend/apps/seo_app/views.py", line 152, in webhook
metrics.parent_key = parent,
This code is creating a tuple. Remove the comma at the end of the line.