ทำให้โปรไฟล์ผู้ใช้ปรากฏแก่ผู้ใช้ทั้งหมด รวมถึง AnonyMouseUser() บน Django

ฉันกำลังพยายามสร้าง UserProfileView ด้วยชื่อผู้ใช้ของผู้ใช้ใน url ที่จริงแล้วมันใช้งานได้กับการตั้งค่าจริง ปัญหาคือส่วนขยายชื่อผู้ใช้ใดๆ ใน URL เปลี่ยนเส้นทางไปยังโปรไฟล์ของผู้ใช้ที่เข้าสู่ระบบ และไม่มีข้อมูลมาที่เทมเพลตเมื่อฉันพยายามไปที่โปรไฟล์โดยไม่ต้องลงชื่อเข้าใช้ นี่คือรหัสของฉัน ขอขอบคุณสำหรับความช่วยเหลือใดๆ

รุ่น.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)

มุมมอง.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
ถูกต้องแล้ว User model มีชื่อผู้ใช้ attr นอกจากนี้ โมเดลโปรไฟล์ยังเชื่อมต่อโดย OneToOneField กับโมเดลผู้ใช้   -  person Ediz    schedule 16.10.2020
comment
คุณสามารถสร้าง UserView แทน UserProfileView ที่ใช้ User model แทน 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