Django Admin封禁用户入表及邮件发送问题排查
解决Django用户封禁功能中的Attribute Error问题
嘿,我来帮你搞定这个报错!首先咱们直击问题根源:你在代码里尝试从request对象调用.report属性,但WSGIRequest本身根本没有这个属性——这说明你找错了获取举报信息的地方,举报数据应该从被封禁用户关联的Report模型实例里拿,而不是请求对象。
错误原因拆解
你当前的代码大概率写了类似request.report.reason的语句,但request是用来收集请求信息(比如用户请求参数、会话等)的对象,和用户的举报记录完全不沾边。正确的姿势是先拿到要封禁的User实例,再通过模型间的关联关系获取对应的Report和Profile数据。
修复步骤&示例代码
假设你的模型关联是这样定义的(如果不是,你可以根据实际情况调整关联字段):
# 模型定义示例 from django.contrib.auth.models import User from django.db import models from django.utils import timezone class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile") # 你的Profile其他字段,比如昵称、头像等 class Report(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reports") reason = models.TextField(verbose_name="举报原因") created_at = models.DateTimeField(auto_now_add=True) # 举报的其他字段,比如举报者、举报类型等 class Banned_User(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) profile = models.ForeignKey(Profile, on_delete=models.CASCADE) report_reason = models.TextField(verbose_name="封禁原因") banned_at = models.DateTimeField(default=timezone.now)
1. 修正视图/Admin Action中的封禁逻辑
如果是在Admin后台执行封禁操作(报错路径/admin/api/profile/指向Admin页面),你可以给UserAdmin添加自定义Action,逻辑如下:
from django.contrib import admin from django.core.mail import send_mail from django.utils import timezone from .models import User, Banned_User @admin.action(description="封禁选中的用户") def ban_selected_users(modeladmin, request, queryset): for user in queryset: # 1. 封禁用户:设置is_active为False user.is_active = False user.save() # 2. 获取关联的Profile和最新举报记录 # 这里假设一个用户有多条举报,取最新的一条作为封禁依据 profile = user.profile latest_report = user.reports.latest("created_at") # 3. 存入Banned_User表 Banned_User.objects.create( user=user, profile=profile, report_reason=latest_report.reason, banned_at=timezone.now() ) # 4. 发送封禁通知邮件 subject = "你的账号已被封禁" message = f""" 您好,您的账号因以下原因被封禁: {latest_report.reason} 封禁时间:{timezone.now().strftime('%Y-%m-%d %H:%M:%S')} """ send_mail( subject=subject, message=message, from_email="your-admin-email@example.com", recipient_list=[user.email], fail_silently=False ) class UserAdmin(admin.ModelAdmin): actions = [ban_selected_users] # 其他Admin配置... admin.site.register(User, UserAdmin)
如果是在普通视图中处理封禁,逻辑类似:
from django.shortcuts import get_object_or_404 from django.http import JsonResponse from django.core.mail import send_mail from django.utils import timezone from .models import User, Banned_User def ban_user(request, user_id): if request.method == "POST": user = get_object_or_404(User, id=user_id) # 封禁用户 user.is_active = False user.save() # 获取关联数据 profile = user.profile latest_report = user.reports.latest("created_at") # 写入Banned_User Banned_User.objects.create( user=user, profile=profile, report_reason=latest_report.reason, banned_at=timezone.now() ) # 发送邮件 # 邮件代码和上面Admin Action中的一致... return JsonResponse({"status": "success", "message": "用户已封禁并发送通知"})
关键注意点
- 确保模型间的
related_name设置正确:比如Report中的related_name="reports",让你可以通过user.reports直接获取该用户的所有举报记录。 - 如果一个用户可能有多条举报,要明确取哪一条作为封禁依据(比如最新的、审核通过的),避免报错。
- 邮件发送需要在Django配置中正确设置邮件后端(比如SMTP),否则邮件无法正常发出。
内容的提问来源于stack exchange,提问作者Shadowwz
相关产品推荐
相关产品推荐

