Django DetailView ValueError: Поле 'id' ожидало число, но получило 'Ryan'

Я создал страницу профиля, которая использует DetailView, но страница профиля просто не работает на вновь созданных пользователях и выдает мне это сообщение об ошибке:

Урл

urlpatterns = [
    path('user/<str:username>/', UserProfileView.as_view(), name='user-profile'),
    ...
]

Вид:

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

и шаблон:

{% extends 'blog/base.html' %}
{% block title %}{{ view.kwargs.username }}'s Profile{% endblock title %}
{% block content %}
    <div class="content-section">
        <div class="media">
            <img class="rounded-circle account-img" src="{{ profile_user.profile.image.url }}">
            <div class="media-body">
                <h2 class="account-heading">{{ view.kwargs.username }}</h2>
                <p class="text-secondary">{{ profile_user.email }}</p>
                <p class="article-content">{{ profile_user.profile.rank }}</p>
                <p class="article-content">{{ profile_user.profile.bio }}</p>
            </div>
        </div>
        {% if profile_user == user %}
            <a class="btn btn-outline-secondary ml-2" href="{% url 'change_profile' %}">Edit Profile</a>
        {% endif %}
    </div>
    ...

Я не уверен, связано ли это с созданием/регистрацией пользователя, поэтому я также включил функцию регистрации

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})

сигналы

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()

и модель профиля

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)

Я новичок в django, я знаю, что, вероятно, предоставил много бесполезной информации, спасибо за вашу помощь:)

Вы используете username для получения запроса

context['requests'] = Request.objects.filter(teacher=user.username, completed=False).order_by('-request_time')

Я предполагаю, что учитель - это Профиль в вашей модели, в любом случае, вы фильтруете по username, а teacher - это ForeginKey, который призрак id для фильтрации. Поэтому вам нужно удалить username и фильтровать только teacher=user. Обратите внимание, что если учитель не является ForeignKey для пользователя, вам может понадобиться использовать teacher__user=user в качестве фильтра.

В Teacher == user.username вы пытаетесь сравнить int и str.

Я предполагаю, что у вас обе модели связаны иностранным ключом в user с teacher. Попробуйте использовать id в этом отношении для сопоставления с учителем.

Редактирование: Вы можете задаться вопросом, почему ваш "учитель" - int, когда вы (вероятно) объявили str имя для модели, и ответ заключается в том, что django по умолчанию предоставляет автоинкрементные целочисленные id для всех моделей и использует эти id для создания Foreign keys. Вы также могли бы сопоставить user.id с внешним ключом teacher для модели user, если вы так структурировали свои отношения.

Вернуться на верх