【问题标题】:How to add Banned Users to table,and send details to user's email within Django Admin如何将禁止用户添加到表中,并将详细信息发送到 Django Admin 中的用户电子邮件
【发布时间】:2018-10-20 06:25:24
【问题描述】:

我有一个简单的禁止功能,将用户活动设置为假,还有一个基本的电子邮件功能来发送电子邮件。我正在使用的表是User,Profile,Report & Banned_User 表。

我期待:

  1. 将用户Profile,Reason_reportedReport 表和datetime 添加到 Banned_User 表一旦被禁止。
  2. 将这些详细信息发送到用户电子邮件

目前我正在收到一个 'Attribute Error at /admin/api/profile/: WSGIRequest' object has no attribute 'report'' 不知道如何去做这两件事。

def banning_users(self, request, queryset):

for obj in queryset:
    if hasattr(obj, 'user'):
        # This object is a Profile, so lookup the user
        obj = obj.user
    obj.is_active = False

    #email function
    banned_user = Banned_User.objects.create(profile=request.user.profile, report_reasons=request.report.report_reason)
    banned_user.save()
    #Sends ban email to user,does not send through the variables yet
    subject = 'Ban'
    message =   'You have been banned'
    email_from = settings.EMAIL_HOST_USER
    recipient_list = [obj.email]
    send_mail( subject, message,email_from, recipient_list )
    obj.save()


self.message_user(request, "User is banned and Email has been sent")

表格如下:

报告表

class Report(models.Model):
def __str__(self):
    return str.join(str(self.user_reported), str(self.datetime_sent))

TOXICITY = 'Toxicity'
SPORTSMANSHIP = 'Poor sportsmanship'

REPORT_REASON_CHOICES = (
    (TOXICITY, 'Toxicity'),
    (SPORTSMANSHIP, 'Unsportsmanlike Behaviour'),
)

session = models.ForeignKey(
    'Session',
    on_delete=models.PROTECT,
    blank=False,
    null=False,
)

user_reported = models.ForeignKey(
    'Profile',
    on_delete=models.PROTECT,
    blank=False,
    null=False,
    related_name='user_reported_report',
)

sent_by = models.ForeignKey(
    'Profile',
    on_delete=models.PROTECT,
    blank=False,
    null=False,
    related_name='sent_by_report',
)

report_reason = models.CharField(
    max_length=255,
    choices=REPORT_REASON_CHOICES,
    default=TOXICITY,
)

datetime_sent = models.DateTimeField(auto_now_add=True,)

禁止用户表

class Banned_User(models.Model):
def __str__(self):
    return self.user.get_username

profile = models.ForeignKey(
    'Profile',
    on_delete=models.PROTECT,
    blank=False,
    null=False,
    related_name='banned_profile'
)

report_reason = models.ForeignKey(
    'Report',
    on_delete=models.PROTECT,
    blank=True,
    null=True,
)

date_banned = models.DateField(null=True, blank=False,)

简介:

class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT)

def __str__(self):
    return self.user.username

USWEST = 'US-West'
USEAST = 'US-East'
EUROPE = 'Europe'
OCEANIA = 'Oceania'
ASIA = 'Asia'
SOUTHAMERICA = 'South America'
SOUTHAFRICA = 'South Africa'
MIDDLEEAST = 'Middle-East'

PREF_SERVER_CHOICES = (
    (USWEST, 'US-West'),
    (USEAST, 'US-East'),
    (EUROPE, 'Europe'),
    (OCEANIA, 'Oceania'),
    (ASIA, 'Asia'),
    (SOUTHAMERICA, 'South America'),
    (SOUTHAFRICA, 'South Africa'),
    (MIDDLEEAST, 'Middle-East'),
)

pref_server = models.CharField(
    max_length=20,
    choices=PREF_SERVER_CHOICES,
    default=USWEST,
)

TEAMWORK = 'Teamwork'
COMMUNICATION = 'Communication'
SKILL = 'Skill'
SPORTSMANSHIP = 'Sportsmanship'

COMMENDS_CHOICES = (
    (TEAMWORK, 'Teamwork'),
    (COMMUNICATION, 'Communication'),
    (SKILL, 'Skill'),
    (SPORTSMANSHIP, 'Sportsmanship'),
)
teamwork_commends = models.IntegerField(null=False, blank=False, default='0',)
communication_commends = models.IntegerField(null=False, blank=False, default='0',)
skill_commends = models.IntegerField(null=False, blank=False, default='0',)
sportsmanship_commends = models.IntegerField(null=False, blank=False, default='0',)

# Weighting of commends
commend_priority_1 = models.CharField(null=False, blank=False, max_length=20, default=TEAMWORK, choices=COMMENDS_CHOICES,)
commend_priority_2 = models.CharField(null=False, blank=False, max_length=20, default=COMMUNICATION, choices=COMMENDS_CHOICES,)
commend_priority_3 = models.CharField(null=False, blank=False, max_length=20, default=SKILL, choices=COMMENDS_CHOICES,)
commend_priority_4 = models.CharField(null=False, blank=False, max_length=20, default=SPORTSMANSHIP, choices=COMMENDS_CHOICES,)

# Other details
birth_date = models.DateField(null=True, blank=False,)
sessions_played = models.IntegerField(null=False, blank=False, default=0,)
received_ratings = models.IntegerField(null=False, blank=False, default=0,)
in_queue = models.BooleanField(null=False, blank=False, default=False,)

# The users id on discord, which will never change. Current max length is 19, but set to 20 for safe measure (64bit Integer)
discord_id = models.CharField(max_length=20, null=True, blank=True,)

追溯:

AttributeError at /admin/api/profile/

'WSGIRequest' object has no attribute 'report'

Request Method:     POST
Request URL:    http://127.0.0.1/admin/api/profile/
Django Version:     2.0.5
Exception Type:     AttributeError
Exception Value:    

'WSGIRequest' object has no attribute 'report'

Exception Location:     /home/mihir/Capstone-Project/siteroot/apps/api/admin.py in banning_users, line 31
Python Executable:  /usr/bin/python3.6
Python Version:     3.6.5
Python Path:    

['/home/mihir/Capstone-Project/siteroot',
 '/usr/lib/python36.zip',
 '/usr/lib/python3.6',
 '/usr/lib/python3.6/lib-dynload',
 '/usr/local/lib/python3.6/dist-packages',
 '/usr/lib/python3/dist-packages',
 '/var/www/CapstoneProject/siteroot',
 '/var/www/CapstoneProject/siteroot/mysite']

Server time:    Thu, 10 May 2018 03:36:51 +0000

新代码:

    def banning_users(self, request, queryset):

    for obj in queryset:
        if hasattr(obj, 'user'):
            # This object is a Profile, so lookup the user
            obj = obj.user
        obj.is_active = False

        banned_user = Banned_User.objects.create(profile=request.user.profile)
        banned_user.report_reason.add(request.user.profile.user_reported_report.all())
        banned_user.save()
        #Sends ban email to user,does not send through the variables yet
        subject = 'Ban'
        message =   'You have been banned for being trash'
        email_from = settings.EMAIL_HOST_USER
        recipient_list = [obj.email]
        send_mail( subject, message,email_from, recipient_list )
        obj.save()

【问题讨论】:

  • 请将完整的错误回溯添加到您的问题中!
  • 已编辑并添加
  • banned_user.report_reason.add(request.user.profile.user_reported_report.all()) 遇到的问题是什么?
  • 我在代码中遇到了同样的 TYPE 错误
  • 我无法帮助您,因为我不知道您尝试了什么,请更新您的代码。

标签: python django django-models django-admin django-email


【解决方案1】:

我期待:

  1. 将用户个人资料、Reason_reported from Report 表和他们被禁止的日期时间添加到 Banned_User 表中。

  2. 将这些详细信息发送到用户电子邮件

将您的问题分解为实际问题,步骤是首先创建封禁报告,然后添加用户,最后发送电子邮件。

错误消息告诉您request 对象没有report 属性,这是有道理的,因为它与用户相关联的报告,而不是请求。

def banning_users(self, request, queryset):

    for obj in queryset:
        if hasattr(obj, 'user'):
            # This object is a Profile, so lookup the user
            profile = obj
            user = obj.user
        user.is_active = False

        # Get the report(s) for this user
        user_reports = Report.objects.filter(user_reported=profile)

        # Go through each report, in case there are multiples,
        # add a record in the ban table

        banned_reasons = []

        for report in user_reports:
            ban_record = Banned_User.create(profile=profile, report_reason=report, date_banned=datetime.datetime.today())
            banned_reasons.append(report.get_report_reason_display())

        # Send the email
        subject = 'Ban'
        message = 'You have been banned for the following reasons: {}'
        message.format(','.join(banned_reasons))
        email_from = settings.EMAIL_HOST_USER
        recipient_list = [user.email]
        send_mail( subject, message,email_from, recipient_list)

    self.message_user(request, "User is banned and Email has been sent")

【讨论】:

  • 报表模型中没有user_profile,你的意思是改成User_reported吗?
  • 呃,我在禁止时收到了一个有趣的错误AttributeError at /admin/api/profile/ type object 'Banned_User' has no attribute 'create',这怎么可能?
  • 通过更改为 Banned_User.objects.create 使其工作,Function 现在发送电子邮件!问题是电子邮件仅显示“您因以下原因被禁止:{}”而没有写任何实际原因。
【解决方案2】:

问题来自这一行:

banned_user = Banned_User.objects.create(profile=request.user.profile, 
           report_reasons=request.report.report_reason)

您正在尝试访问请求中的报告,而请求没有此属性。

我建议您将ForeignKey 更改为ManyToManyField,因为一个用户可以有多个报告。

class Banned_User(models.Model):
    def __str__(self):
        return self.user.get_username

    profile = models.ForeignKey('Profile',on_delete=models.PROTECT,
         blank=False, null=False, related_name='banned_profile',)

    report_reasons = models.ManyToManyField('Report',blank=True)

所以你会得到这个:

if hasattr(obj, 'user'):
    # This object is a Profile, so lookup the user
    obj = obj.user
obj.is_active = False

# email function
banned_user = Banned_User.objects.create(profile=request.user.profile)
banned_user.report_reasons.add(request.user.profile.user_reported_report.all())
# rest of code 

【讨论】:

  • 返回一个ValueError at /admin/api/profile/ Cannot assign "<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x7ffaa6e35550>": "Banned_User.report_reason" must be a "Report" instance. ERROR。
  • 我已经添加了我的个人资料模型,如果它有助于查看关系,我之前没有添加它,以免问题太冗长
  • 是的,在你编辑之前,我已经更新了我的答案,因为很明显Profile 对用户有OneToOne,就像我在许多 django 项目中看到的那样。检查我的答案
  • 我已经检查了您更新的评论并在编辑我的评论之前重试了代码:)。我评论中的错误来自更新的代码
  • 哦,抱歉,这是一个 RelatedManaget,所以您可以使用 all() 访问它,然后选择您想要的,例如第一个:更新了我的答案
【解决方案3】:

这是最终让它工作的代码 :) 感谢大家的帮助

def banning_users(self, request, queryset):

    for obj in queryset:
        if hasattr(obj, 'user'):
            # This object is a Profile, so lookup the user
            profile = obj
            user = obj.user
        user.is_active = False
        user.save()

        banned_reasons = []

    
        banned_user = profile.banned_profile.create(profile=profile)
        reports = banned_user.profile.user_reported_report.all()
        banned_user.save()
        for report in reports:
            banned_user.report_reason.add(report)
        
        # Send the email
        subject = 'Ban'
        message = 'You have been banned for the following reasons: []'
        email_from = settings.EMAIL_HOST_USER
        recipient_list = [user.email]
        send_mail( subject, message,email_from, recipient_list)

    self.message_user(request, "User is banned and Email has been sent")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2018-07-06
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    相关资源
    最近更新 更多