繁体   English   中英

AttributeError: 'NoneType' object 没有属性 'get' - 当我有数据并且没有字段为 None 时如何解决?

[英]AttributeError: 'NoneType' object has no attribute 'get' - How to solve it when I even have the data and no field is None?

我正在创建一个 Django 应用程序。 我将编写系统应该如何工作的简短摘要,然后我将分享我的代码。

当用户(学生)将 go 转到performance_calculator.html时,他/她将看到一个文本框,他/她必须在其中输入相关主题名称。 输入主题名称后,他/她将单击“计算”按钮,在另一端(服务器端)将采用输入的名称,系统将搜索该用户(学生)的该主题的详细信息(进度)从 Detail Model 使用主题名称和该用户名作为过滤器。 获取进度详细信息后,详细信息中的每个值都将分配给单独的单个变量。 这些变量将作为参数传递给fuzz_algo() function(计算性能的模糊逻辑算法),得到结果后,结果将使用 Django 消息模块转发到客户端(前端)。

这是摘要,现在我在系统尝试获取用户(正在使用系统的学生)的主题(其名称由用户输入)的进度详细信息时收到错误。 并且错误是AttributeError: 'NoneType' object has no attribute 'get' 我知道当我们从某个地方收到None并且我们尝试从None获取某些东西时会发生此错误。 但是我已经使用管理面板填充了详细信息 Model 和主题 Model(附有截图)。 我不知道为什么我得到None并且由于None ,这个AttributeError

我的观点.py

def performanceCalculator(request):
    skype = 0
    internal_course = 0
    prg_lab = 0
    mid_marks = 0
    final_marks = 0
    sub = 0
    if request.method == 'POST':
        performance_form = PerformanceCalculatorForm(request.POST)

        if performance_form.is_valid():
            performance_form.save()

            sub = performance_form.cleaned_data.get('subject')
            skype = Detail.objects.filter(subject__subject=sub, user__username=User.username).values().first().get('skype_session_attendance')
            internal_course = Detail.objects.filter(subject__subject=sub, user__username=User.username).values().first().get('internal_course_marks')
            prg_lab = Detail.objects.filter(subject__subject=sub, user__username=User.username).values().first().get('programming_lab_activity')
            mid_marks = Detail.objects.filter(subject__subject=sub, user__username=User.username).values().first().get('mid_term_marks')
            final_marks = Detail.objects.filter(subject__subject=sub, user__username=User.username).values().first().get('final_term_marks')

            result = fuzz_algo(skype, internal_course, prg_lab, mid_marks, final_marks)

            messages.success(request, result)

            return redirect('performance_calculator')
    else:
        performance_form = PerformanceCalculatorForm()

    context = {
        'performance_form': performance_form
    }

    return render(request, 'users/performance_calculator.html', context)

我的模型.py

class Subject(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=100)

    def __str__(self):
        return '{} ({})'.format(self.subject, self.user.username)


class Detail(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.OneToOneField(Subject, on_delete=models.CASCADE)
    skype_session_attendance = models.FloatField()
    internal_course_marks = models.FloatField()
    programming_lab_activity = models.FloatField()
    mid_term_marks = models.FloatField()
    final_term_marks = models.FloatField()

    def __str__(self):
        return f'{self.subject, (self.user.username)} Details'

class Sub(models.Model):
    s = models.CharField(max_length=100

我的 forms.py

class PerformanceCalculatorForm(forms.ModelForm):
    subject = forms.CharField(max_length=100)

    class Meta:
        model = Sub
        fields = ['subject']

我的模板(users/performance_calculator.html)

{% if not request.user.is_superuser and not request.user.is_staff %}
                        <div class="account-heading">
                            <h2>
                                Performance Calculator
                            </h2>
                        </div>

                        <div class="content-section">
                            <form method="POST">
                                {% csrf_token %}
                                <fieldset class="form-group">
                                    <legend class="border-bottom mb-4"></legend>
                                    {{ performance_form|crispy }}
                                </fieldset>
                                <div class="from-group">
                                    <button class="btn btn-outline-info" type="submit">Calculate</button>
                                </div>
                            </form>
                        </div>
                    {% endif %}

这是我得到的完整错误:

AttributeError at /esacp/performance-calculator/
'NoneType' object has no attribute 'get'
Request Method: POST
Request URL:    http://localhost:8000/esacp/performance-calculator/
Django Version: 3.0.3
Exception Type: AttributeError
Exception Value:    
'NoneType' object has no attribute 'get'
Exception Location: C:\Users\khubi\OneDrive\Desktop\FYP\test_phase\users\views.py in performanceCalculator, line 61
Python Executable:  C:\environments\bsse_fyp\Scripts\python.exe
Python Version: 3.8.1
Python Path:    
['C:\\Users\\khubi\\OneDrive\\Desktop\\FYP\\test_phase',
 'C:\\Users\\khubi\\AppData\\Local\\Programs\\Python\\Python38-32\\python38.zip',
 'C:\\Users\\khubi\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs',
 'C:\\Users\\khubi\\AppData\\Local\\Programs\\Python\\Python38-32\\lib',
 'C:\\Users\\khubi\\AppData\\Local\\Programs\\Python\\Python38-32',
 'C:\\environments\\bsse_fyp',
 'C:\\environments\\bsse_fyp\\lib\\site-packages']
Server time:    Thu, 14 May 2020 11:55:41 +0000

现在,下面是管理面板的屏幕截图,显示了填充的主题和详细信息 model: 这是主 Django 管理面板,看到右侧的操作了吗? 在此处输入图像描述

这是科目 Model,见添加了 4 个科目,一个学生的 2 个,其他的 2 个。 在此处输入图像描述

这是用户(学生)的一个主题的详细信息 Model。 查看详细信息已输入且字段不为None或为空在此处输入图像描述

现在我不明白,为什么在没有空的地方出现错误。

PS 是的,我使用上面屏幕截图中填充的主题详细信息的同一用户(学生)登录。 如果您在模板中看到,我在开始时有if condition ,如果用户不是员工也不是超级用户,那么只会显示该表单。 所以很明显,使用 Django 管理面板登录,我不会看到性能计算器表格,如果我使用普通帐户登录,我只会看到表格。 但我仍然收到错误消息。

forms.py中,您已将Meta.model设置为Sub并将Meta.fields设置为['subject']

models.py中,model Sub没有“主题”属性。

澄清:通过这次查看您的整个代码,您已经将数据插入到数据库中,并且您的表单仅对这些数据执行 GET ......因此,出于性能考虑,不应保存表单(因为它将是每次发布时创建新的 object)。 这意味着更好的方法应该被编码为 GET 而不是 POST ......

但是可以说这是一个特殊情况,您想这样做是因为您想... 这次我将直接修改您的代码,乍一看很头疼,因为它查询太多,因此效率很低。

视图.py

def performanceCalculator(request):
    if request.method == 'POST':
        performance_form = PerformanceCalculatorForm(request.POST)

        if performance_form.is_valid():
            #performance_form.save() #dont save because you dont need to.
            #just process it by getting the data
            sub = performance_form.cleaned_data['subject']

            detail = Detail.objects.all().filter(user=request.user, subject=sub).first()
            #get the unique object that matches the filters
            #and I think what is causing you the Nonetype error is your queries
            #(I saw filter(subject__subject=...) and the OneToOneField doesn't 
            #behave the same as a ForeignKey and that may be the case.)

            #now fetch every field into the function
            result = fuzz_algo(detail.skype_session_attendance, detail.internal_course_marks, detail.programming_lab_activity, detail.mid_term_marks, detail.final_term_marks)

            messages.success(request, result) #if it raises int related error, include the str filter later.

            return redirect('performance_calculator')
    else:
        performance_form = PerformanceCalculatorForm()

    context = {
        'performance_form': performance_form
    }

    return render(request, 'users/performance_calculator.html', context)

编辑:忘记添加这部分

在你的models.py中......拥有model Subject没有多大意义,它是有2个用户关系的原因......

所以更清洁的 model 将是:

#removed the Subject model

class Detail(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=15) #modified to be a CharField
    skype_session_attendance = models.FloatField()
    internal_course_marks = models.FloatField()
    programming_lab_activity = models.FloatField()
    mid_term_marks = models.FloatField()
    final_term_marks = models.FloatField()

    def __str__(self):
        return f'{self.subject, (self.user.username)} Details'

#also the Sub class

编辑:添加 .first .first()以获取查询集上的第一个 object

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM