I created a profile page that uses DetailView, but the profile page just doesn't work on newly created users and is giving me this error message:
Internal Server Error: /user/Ryan/
Traceback (most recent call last):
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1822, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'Ryan'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/views/generic/base.py", line 101, in dispatch
return handler(request, *args, **kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/views/generic/detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "/Users/raymond/Documents/GitHub/Management/blog/views.py", line 32, in get_context_data
context['requests'] = Request.objects.filter(teacher=user.username, completed=False).order_by('-request_time')
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/query.py", line 974, in filter
return self._filter_or_exclude(False, args, kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/query.py", line 992, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/query.py", line 999, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1375, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1396, in _add_q
child_clause, needed_inner = self.build_filter(
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1329, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1180, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/lookups.py", line 22, in __init__
self.rhs = self.get_prep_lookup()
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/fields/related_lookups.py", line 120, in get_prep_lookup
self.rhs = target_field.get_prep_value(self.rhs)
File "/Users/raymond/opt/anaconda3/envs/python388/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1824, in get_prep_value
raise e.__class__(
ValueError: Field 'id' expected a number but got 'Ryan'.
The url
urlpatterns = [
path('user/<str:username>/', UserProfileView.as_view(), name='user-profile'),
...
]
The view:
class UserProfileView(DetailView):
model = User
template_name = 'blog/user_profile.html'
def get_object(self):
return get_object_or_404(User, pk=self.request.user.id)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = get_object_or_404(User, username=self.kwargs.get('username'))
context['profile_user'] = user
if user.is_superuser:
context['requests'] = Request.objects.all().order_by('-request_time')
elif user.profile.teacher_status:
context['requests'] = Request.objects.filter(teacher=user.username, completed=False).order_by('-request_time')
else:
context['requests'] = Request.objects.filter(student=user, completed=False).order_by('-request_time')
return context
and the template:
{% extends 'blog/base.html' %}
{% block title %}{{ view.kwargs.username }}'s Profile{% endblock title %}
{% block content %}
<div >
<div >
<img src="{{ profile_user.profile.image.url }}">
<div >
<h2 >{{ view.kwargs.username }}</h2>
<p >{{ profile_user.email }}</p>
<p >{{ profile_user.profile.rank }}</p>
<p >{{ profile_user.profile.bio }}</p>
</div>
</div>
{% if profile_user == user %}
<a href="{% url 'change_profile' %}">Edit Profile</a>
{% endif %}
</div>
...
I am not sure if it is something related to the User creation/registration, so I also included the registration function
def register(request):
if request.method == 'POST':
f = UserRegisterForm(request.POST)
if f.is_valid():
p = f.save()
p.refresh_from_db()
p.profile.rank = f.cleaned_data.get('rank')
p.save()
username = f.cleaned_data.get('username')
messages.success(request, f'Account created for {username}')
return redirect('login')
else:
f = UserRegisterForm()
return render(request, 'users/register.html', {'form':f})
the signals
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
and the Profile model
class Profile(models.Model):
RANKS = [(f'{i}K', f'{i}K') for i in range(1,19)]
for i in range(1, 10):
RANKS.append((f'{i}D', f'{i}D'))
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=225, blank=True, default='')
rank = models.CharField(max_length=3, default='18K', choices=RANKS)
teacher_status = models.BooleanField(default=False)
def __str__(self) -> str:
return f"{self.user.username}'s Profile"
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
img.thumbnail((300,300))
img.save(self.image.path)
I am new to django, I know I've probably provided a lot of useless information, thank you for your help:)
CodePudding user response:
You are using the username
to get the Request
context['requests'] = Request.objects.filter(teacher=user.username, completed=False).order_by('-request_time')
I'm guessing that teacher is a Profile in your model, in any case, you are filtering by the username
and teacher
is a ForeginKey that is specting an id
to filter. So, what you need to do is remove the username
and filter only teacher=user
. Please note that if teacher is not a ForeignKey to user you may need to use teacher__user=user
as a filter.
CodePudding user response:
In Teacher == user.username you are trying to compare an int and a str.
I'm guessing that you have both models related with a Foreign key in user to a teacher. Try use the id on that relation to match with teacher.
Edit: You may wonder why your "teacher" is int when you (probably) declared a str name for the model, and the answer is that django provides by default autoincremental integer ids to all models and uses that id to create Foreign keys. You could also match the user.id with the teacher Foreign key to the user model, if that's how you structured you relationship.