RelatedObjectDoesNotExist at /customer_creation
User has no employee.
Request Method: |
POST |
Request URL: |
http://127.0.0.1:8000/customer_creation |
Django Version: |
4.1.7 |
Exception Type: |
RelatedObjectDoesNotExist |
Exception Value: |
User has no employee. |
Exception Location: |
/Users/my_name/Library/Python/3.9/lib/python/site-packages/django/db/models/fields/related_descriptors.py, line 463, in get
|
Raised during: |
site_users.views.customerCreation |
Python Executable: |
/Library/Developer/CommandLineTools/usr/bin/python3 |
Python Version: |
3.9.6 |
trackback: if request.user.employee.business:
Side note: It’s a lot more helpful to get the traceback from the console where you’re running the server than trying to copy the error appearing in the browser.
Okay, like this?
Traceback (most recent call last):
File "/Users/my_name/Library/Python/3.9/lib/python/site-packages/django/core/handlers/exception.py", line 56, in inner
response = get_response(request)
File "/Users/my_name/Library/Python/3.9/lib/python/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/my_name/Desktop/cs/Django/crms/site_users/views.py", line 143, in customerCreation
if request.user.employee.business:
File "/Users/my_name/Library/Python/3.9/lib/python/site-packages/django/utils/functional.py", line 268, in inner
return func(_wrapped, *args)
File "/Users/my_name/Library/Python/3.9/lib/python/site-packages/django/db/models/fields/related_descriptors.py", line 463, in __get__
raise self.RelatedObjectDoesNotExist(
site_users.models.User.employee.RelatedObjectDoesNotExist: User has no employee.
[31/May/2023 16:36:18] "POST /customer_creation HTTP/1.1" 500 71387
1 Like
The problem with this line:
is that if there is no employee
object related to user
, then trying to reference employee.business
will fail with this error.
You have a couple different ways to test this - you can either add additional conditions to the if
to prevent this, or you can wrap this in a try
/ except
block to catch the error.
1 Like
Okay, the try/except is the easy way. I will do that if I can’t think of another way right now.
Adding additional conditions to the *if * seems like a better way to go. In the database tables, the user_employee table has an id for business. So are you saying to check for an integer in the statement? Rather than for the string object in business? I was under the impression the program checks the user_employee_business table for a string and not an integer or it checks that it’s not NULL.
Tried this:
if request.user.employee.business != None:
Same error.
You need to verify whether user.employee
even exists before thinking of trying to check user.employee.business
. For example, if hasattr(request.user, 'employee'): ...
1 Like
Mind blown. That works.
I would have never guessed that hasattr
can check classes/tables like that. Game changer knowledge you share.
The last step, now that the database tables are structured and I can access each user, is to get a search feature working. There are many ways to do this, do you have a certain path you would take for this? I am messing with Django-filters now, but can’t seem to get it to work.
Goal: Have an employee search for customers in the employee’s business.
Current setup, No Errors, just no results, database has customers and I am trying to search them, but " Hey! You Forgot to Search For a User. ." is popping up instead.
forms.py
import django_filters
class CustomerFilter(django_filters.FilterSet):
business = django_filters.CharFilter(name='business', lookup_expr='icontains')
customer = django_filters.CharFilter(name='customer', lookup_expr='icontains')
user = django_filters.CharFilter(name='user', lookup_expr='icontains')
class Meta:
model = Customer
fields = ['business', 'customer', 'user', ]
views.py
def searchUsers(request):
result = Customer.objects.all()
query = request.GET.get("query")
if query:
result = result.filter(
Q(user__customer__icontains=query) |
)
user_filter = CustomerFilter(request.GET, queryset=result)
return render(request, "search_users.html", {'filter': user_filter,
'query': query})
search_users.html
{% block content %}
<center>
{% if query %}
<h1> you Searched for {{ query }} . . </h1>
{% for x in user_filter %}
{{ x.first_name }}
{{ x.last_name}}<p>
{{x}}<br/>
{% endfor %}
{%else %}
<h1> Hey! You Forgot to Search For a User. . . </h1>
{% endif %}
</center>
{% endblock content %}
Keep in mind that User
is an object, as is Customer
. If you’re going to filter by a “name”, you need to ensure that you’re referencing the field within the model and not just the model itself.
For example User.objects.filter(customer='Acme')
isn’t going to give you all customers of business “Acme”. Neither is User.objects.filter(customer__business='Acme')
, since that’s just the reference to the Business
model. You would need to search for customer__business__business
to be comparing with the CharField in that model.
(Note: I don’t use django-filters, I don’t have any specific advice to offer you regarding it.)
1 Like
I got the search to work, bringing us to our answer combined with Ken’s Model set up.
def searchUsers(request):
qs_owned_businesses = Employee.objects.filter(user = request.user).values(‘business_id’)
qs_biz_customers = Customer.objects.filter(business_id__in=qs_owned_businesses).values(‘user_id’)
if request.method == “GET”:
query = request.GET.get(‘search’)
if query == ‘’:
query = ‘None’
results = User.objects.filter(username__icontains=query, id__in=qs_biz_customers)
return render(request, ‘search_users.html’, {‘query’: query, ‘results’: results, })