在 Django 中停用用户及其配置文件的正确方法

Correct way to deactivate user and its profile in Django

我创建了一个视图,登录用户应该可以在其中停用其配置文件。
我希望看到更改反映在我的管理部分,但事实并非如此。
看起来用户正在被停用,但 user.profile 没有。
我很困惑,因为在我按照 Django 文档完成了整个项目之后,似乎缺少正确管理用户停用的方法。
我想严格遵守 Class-Based-Views。

我的实际代码:

# models.py

# Model to handle user profiles
class Profile(models.Model):
    """Create user profiles and manage their attributes"""
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=180, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)
    avatar = models.ImageField(upload_to='social/static/social/avatars/', null=True, blank=True) 
    follows = models.ManyToManyField('self', related_name='followed_by', symmetrical=False, blank=True)
    is_active = models.BooleanField(default=True)
    
    def __str__(self):
        return self.user.username

# Signal function to create a profile when a user is created
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        user_profile = Profile(user=instance)
        user_profile.save()

# views.py
class ProfileInactive(View):
"""User can made its profile unactive"""
model = models.Profile
template_name = 'social/profile_delete.html'

# Users can delete only their profile, or get a 404 error
def get_queryset(self):
    owner = self.request.user
    return self.model.objects.filter(user=owner)

def get(self, request, username):
    profile = get_object_or_404(models.Profile, user__username=self.kwargs['username'])
    return render(request, self.template_name, {'profile': profile})

def post(self, request, username):
    owner = self.request.user
    profile = request.user
    print(owner, profile)
    if owner == profile:
        profile.is_active = False
        owner.is_active = False
        profile.save()
        owner.save()
        logout(request)
    else:
        raise Http404
    return redirect('social:register')

和相关的 url 路径:

path('profile_delete/<str:username>/', login_required(views.ProfileInactive.as_view()), name='profile_delete'),

问题是:

示例:
{{ profile.user.is_active }} 显示 False
{{ profile.is_active }} 显示 True

我尝试了很多组合,但无法解决。

此外,我想知道是否有一种 pythonic 方式来管理我期望在任何 django 应用程序中非常常见\需要的功能。

感谢您给我的任何提示!

所有者和个人资料是 request.user

解决方案 #1

在您的模型中添加 related_name:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,related_name="profile")

在您的 ProfileInactive.post 方法中:

def post(self, request, username):
    owner = self.request.user
    profile = request.user.profile #+
    print(owner, profile)
    if owner == profile:
        profile.is_active = False
        owner.is_active = False
        profile.save()
        owner.save()
        logout(request)
    else:
        raise Http404
    return redirect('social:register')

解决方案 #2

使用信号。

创建 signals.py 文件。 添加此代码段:

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User

@receiver(post_save,sender=User)
def update_profile(sender, instance, *args, **kwargs):
    user= instance
    profile = user.profile
    if user.is_active == False:
         profile.is_active = False
         profile.save()
    else:
         profile.is_active = True
         profile.save()

在您的“post”函数中,您使用的是相同的用户资源。即“self.request.user”和“request.user”是同一回事。

您应该改为执行 Profile.objects.get(user = request.user) 并更改那里的 is_active 标志。