You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

封禁用户并写入Banned_User表时遇TypeError问题求助

Fixing the "Direct Assignment to Many-to-Many Set" Error in Your Banning Function

Alright, let's break down what's causing that TypeError and get your user banning logic working correctly.

1. Why the Error Happens

The error message says it plainly: you can't directly assign a value to a many-to-many field when creating a model instance. Your Banned_User.report_reason is a ManyToManyField, so Django won't let you do report_reason=report in the create() call. Instead, you need to create the Banned_User first, then use methods like add() or set() to link the related Report objects.

2. Corrected Banning Function

Here's the fixed version of your function, with additional improvements to the email logic and required field handling:

from django.utils import timezone

def banning_users(self, request, queryset):
    for obj in queryset:
        if hasattr(obj, 'user'):
            profile = obj
            user = obj.user
            
            # Disable the user account
            user.is_active = False
            user.save()
            
            # Fetch all reports linked to this profile
            user_reports = Report.objects.filter(user_reported=profile)
            banned_reasons = []
            
            # Create the Banned_User record (we'll add reports next)
            # Note: date_banned is required, so we set it to today's date
            ban_record = Banned_User.objects.create(
                profile=profile,
                date_banned=timezone.now().date()
            )
            
            # Link each report to the ban record using add()
            for report in user_reports:
                ban_record.report_reason.add(report)
                banned_reasons.append(report.get_report_reason_display())
            
            # Build a clean, safe email message
            subject = 'Your Account Has Been Banned'
            if banned_reasons:
                formatted_reasons = ', '.join(banned_reasons)
                message = f"You have been banned from the platform for the following reason(s): {formatted_reasons}."
            else:
                message = "You have been banned from the platform."
            
            # Send the notification email
            email_from = settings.EMAIL_HOST_USER
            recipient_list = [user.email]
            
            send_mail(
                subject,
                message,
                email_from,
                recipient_list
            )
            
            self.message_user(request, f"Success: User {user.username} has been banned and a notification email was sent.")

3. Key Fixes & Improvements

  • Many-to-Many Fix: We first create the Banned_User instance, then use ban_record.report_reason.add(report) to associate each report. If you want to add all reports in one go, you could replace the loop with ban_record.report_reason.set(user_reports) instead.
  • Email Logic Fix: The original message had broken string concatenation and risked index errors (if there were fewer than 2 reports). Using str.join() safely combines all reasons into a readable list.
  • Required Field Handling: Your Banned_User.date_banned field is marked blank=False, so we added date_banned=timezone.now().date() to ensure it's populated when creating the record.

4. Optional Model Tweak

To avoid having to specify date_banned every time, you can set a default value directly in the Banned_User model:

from django.utils import timezone

class Banned_User(models.Model):
    def __str__(self):
        return f"{self.profile} - {', '.join([r.report_reason for r in self.report_reason.all()])}"
    
    profile = models.ForeignKey(
        'Profile',
        on_delete=models.PROTECT,
        blank=False,
        null=False,
        related_name='banned_profile'
    )
    report_reason = models.ManyToManyField(
        'Report',
        blank=True,
    )
    date_banned = models.DateField(null=True, blank=False, default=timezone.now)

内容的提问来源于stack exchange,提问作者Shadowwz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:53:58