Сделать профиль пользователя видимым для всех пользователей Включите AnonyMouseUser () в Django

Я пытаюсь создать UserProfileView с именем пользователя в URL-адресе. Собственно с реальными настройками как-то работает. Проблема в том, что любое расширение имени пользователя в URL-адресе перенаправляет на профиль пользователя, вошедшего в систему. И никакая информация не поступает в шаблон, когда я пытаюсь войти в профиль без входа в систему. Вот мой код, любая помощь приветствуется.

models.py

class Profile(models.Model):
  user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
  email = models.EmailField(max_length=150)
  bio = models.TextField(max_length=280, blank=True)
  avatar = models.ImageField(default='default.jpg', upload_to='avatars/')

  def __str__(self):
    return '@{}'.format(self.user.username)

  def save(self):
    super().save()

    img = Image.open(self.avatar.path)

    if img.height > 300 or img.width > 300:
      output_size = (300, 300)
      img.thumbnail(output_size, Image.BICUBIC)
      img.save(self.avatar.path)

views.py

class UserProfileView(SelectRelatedMixin, TemplateView):
  model = Profile
  template_name = 'accounts/profile.html'
  select_related = ('user',)

  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    return context

  def get_success_url(self):
    return reverse('accounts:profile', kwargs={'user': self.object.user})

urls.py

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

profile.html (как я называю связанные данные в шаблоне)

<h3>{{ user.profile }}</h3>
      <p>{{ user.profile.email }}</p>
      <p>{{ user.profile.bio }}</p>
        <h3>{{ profile }}</h3>

* обновление для более четкого объяснения:

вот профиль пользователя при попытке без входа в систему

и профиль того же пользователя здесь при входе в систему. Фактически, он должен отображать профиль пользователя с именем пользователя в URL. но он всегда показывает профиль текущего пользователя по любому URL.


person Ediz    schedule 15.10.2020    source источник
comment
Не очень понятно, в чем ваша проблема   -  person GProst    schedule 15.10.2020
comment
Пытался добавить фото проблемы. надеюсь, теперь это более понятно.   -  person Ediz    schedule 16.10.2020
comment
Есть ли у вас username поле на User или Profile модели? Пытаюсь понять, почему вы используете представление для профиля, а не только для пользователя ...   -  person GProst    schedule 16.10.2020
comment
Правильно, модель пользователя имеет имя пользователя attr. Кроме того, модель профиля связана OneToOneField с моделью пользователя.   -  person Ediz    schedule 16.10.2020
comment
Итак, можете ли вы просто создать UserView вместо UserProfileView, который использует модель User вместо Profile? Не было бы проще? Я вижу, что в шаблоне вы все равно получаете доступ к profile через user.profile ...   -  person GProst    schedule 16.10.2020
comment
Пытался, но по-прежнему отображает информацию о текущем пользователе в шаблоне по любому URL-адресу. Также не работала функция get_queryset. Который; def get_queryset(self): queryset = super().get_queryset() return queryset.filter(user__username__iexact=self.kwargs.get('user.username'))   -  person Ediz    schedule 16.10.2020
comment
Код в комментарии не стоял на блоках. Надеюсь, это ясно.   -  person Ediz    schedule 16.10.2020


Ответы (1)


Вам нужно добавить BaseDetailView, определить get_object метод и добавить 'user' в контекст:

class UserProfileView(SelectRelatedMixin, BaseDetailView, TemplateView):
  model = Profile
  template_name = 'accounts/profile.html'
  select_related = ('user',)

  def get_object(self):
   return self.get_queryset().get(user__username=self.kwargs['username'])

  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    content['user'] = self.object.user
    return context

В качестве альтернативы вы можете основывать свое мнение на модели User, а не Pofile (я думаю, что это немного проще):

class UserProfileView(SelectRelatedMixin, BaseDetailView, TemplateView):
  model = User
  template_name = 'accounts/profile.html'
  select_related = ('profile',)

  def get_object(self):
   return self.get_queryset().get(username=self.kwargs['username'])

  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    content['user'] = self.object
    return context

Или вы можете даже не беспокоиться о добавлении 'user' в контекст и просто получить доступ к пользователю в шаблоне через object

person GProst    schedule 15.10.2020
comment
Обновил мой ответ с некоторыми исправлениями - person GProst; 16.10.2020
comment
Ага, работает! SingleObjectMixin сначала не работала без объектов, но BaseDetailView выполнила эту работу за меня. Спасибо за старания, оценили! - person Ediz; 16.10.2020
comment
Кстати, я думаю, вы также можете заменить BaseDetailView + TemplateVIew, просто используя DetailView - person GProst; 16.10.2020