/writeReview/1 __str__ 处的 Django 模型 TypeError 返回非字符串(int 类型)

Posted

技术标签:

【中文标题】/writeReview/1 __str__ 处的 Django 模型 TypeError 返回非字符串(int 类型)【英文标题】:Django model TypeError at /writeReview/1 __str__ returned non-string (type int) 【发布时间】:2020-07-14 17:41:56 【问题描述】:

我遇到了与上述错误相关的问题(如图 4 所示)。有人可以帮我吗?我在尝试提交将数据保存到 ReviewTable 的表单时看到此错误,如图 2 所示。我还添加了以下代码:


    TypeError at /writeReview/1

    __str__ returned non-string (type int)

    Request Method:     GET
    Request URL:    http://55fde5117b01476bb57eb987ae0e9a37.vfs.cloud9.us-east-2.amazonaws.com/writeReview/1?csrfmiddlewaretoken=yJ0M6sDxPjEZJmJxrR0JMLFYJzboppJ6NGfa5H25D7ieDNTVQKIy9pFhu9WKYsDA&reviewText=This+is+a+test+&rating=2
    Django Version:     3.0.2
    Exception Type:     TypeError
    Exception Value:    

    __str__ returned non-string (type int)

    Exception Location:     /home/ec2-user/.local/lib/python3.6/site-packages/django/db/models/base.py in __repr__, line 518
    Python Executable:  /usr/bin/python36
    Python Version:     3.6.10
    Python Path:    

    ['/home/ec2-user/environment/HangryBirds',
     '/usr/lib64/python3.6',
     '/usr/lib64/python3.6/lib-dynload',
     '/home/ec2-user/.local/lib/python3.6/site-packages',
     '/usr/local/lib64/python3.6/site-packages',
     '/usr/local/lib/python3.6/site-packages',
     '/usr/lib64/python3.6/dist-packages',
     '/usr/lib/python3.6/dist-packages']

    Server time:    Thu, 2 Apr 2020 16:44:16 +0000
    Traceback Switch to copy-and-paste view

        /home/ec2-user/.local/lib/python3.6/site-packages/django/db/models/fields/__init__.py in get_prep_value

                        return int(value)

             …
        ▶ Local vars
        During handling of the above exception (int() argument must be a string, a bytes-like object or a number, not 'RestaurantTable'), another exception occurred:
        /home/ec2-user/.local/lib/python3.6/site-packages/django/core/handlers/exception.py in inner

                        response = get_response(request)

             …
        ▶ Local vars
        /home/ec2-user/.local/lib/python3.6/site-packages/django/core/handlers/base.py in _get_response

                            response = self.process_exception_by_middleware(e, request)

             …
        ▶ Local vars
        /home/ec2-user/.local/lib/python3.6/site-packages/django/core/handlers/base.py in _get_response

                            response = wrapped_callback(request, *callback_args, **callback_kwargs)

             …
        ▶ Local vars
        /home/ec2-user/environment/HangryBirds/home/views.py in writeReview

                    newReview.save()

         ```


Views.py[1]
Here's the views.py file where the form data is saved to the ReviewTable in models.py
def writeReview(request, parameter):
    if request.method == 'GET':
        newReview = ReviewTable()
        username = request.session['username']
        newReview.review = request.GET['reviewText']
        newReview.rating = request.GET['rating']
        newReview.timestamp = datetime.datetime.now()
        newReview.userObj_id = UserTable.objects.filter(username=username)
        newReview.menuObj_id = parameter
        newReview.restObj_id = MenuTable.objects.filter(item_ID=parameter).first().restObj
        newReview.save()
        template = loader.get_template("showReview.html")
        return HttpResponse(template.render())

    else:
        template = loader.get_template("home.html")
        return HttpResponse(template.render())```

Models.py2 这是 ReviewTable 的架构:-


    class ReviewTable(models.Model):
        userObj = models.ForeignKey(UserTable, on_delete=models.CASCADE)
        menuObj = models.ForeignKey(MenuTable, on_delete=models.CASCADE)
        restObj = models.ForeignKey(RestaurantTable, on_delete=models.CASCADE)
        review = models.CharField(max_length=1000)
        timestamp = models.DateTimeField(auto_now=True, editable=True)
        rating = models.IntegerField()

        def __str__(self):
            return self.id```

    ShowReview.html[3]
Here's the html form section where the data is transfered to views.py for saving to the table.
    ```<div class="right-template">
                % for m in menu_ID %
                    <h2> m.item_name </h2>
                    <h2>Reviews</h2>
                    % for r in review_ID %
                        % if r.menuObj_id == m.item_ID %
                            <h4> r.userObj.username </h4>
                            <p> r.review </p>
                            <p> r.timestamp </p>
                            <p> r.rating </p>
                        % endif %
                    % endfor %
                     <h2>Write a Review</h2>
                     % block content %
                        <form method="GET" action="% url 'writeReview' parameter=m.item_ID %" >
                            % csrf_token %
                            <div>
                                <textarea id="reviewText" name="reviewText" rows="5" cols="50" max_length="900"></textarea>
                                <label for="rating">Rating</label>
                                <input type="number" name="rating" max_length="5" id=rating>
                                <button type="submit" class="btnRest">Submit</a>
                            </div>    
                        </form>
                    % endblock %
                  % endfor %

错误图片4

【问题讨论】:

你应该在你的问题中显示代码而不是使用图片,这样更容易帮助人们。 idownvotedbecau.se/imageofcode我没有dv,但是请复制问题中的代码,不是图像的代码。 @X18PY 现在看看。很抱歉给您带来不便。 【参考方案1】:

正如例外所说,__str__ 应该返回一个字符串self.id,是 int,而不是字符串。您可以使用str(..) 将 int 转换为字符串:

class ReviewTable(models.Model):
    # …

    def __str__(self):
        return str(self.id)

请注意,在您看来,您应该使用.newReview.restObj = restaurant_object.newReview.restObj_id = id_of_restaurant_object

def writeReview(request, parameter):
    if request.method == 'GET':
        newReview = ReviewTable()
        username = request.session['username']
        newReview.review = request.GET['reviewText']
        newReview.rating = request.GET['rating']
        newReview.timestamp = datetime.datetime.now()
        newReview.userObj = UserTable.objects.get(username=username)
        newReview.menuObj_id = parameter
        newReview.restObj = MenuTable.objects.first(item_ID=parameter).restObj
        newReview.save()
        template = loader.get_template("showReview.html")
        return HttpResponse(template.render())

    else:
        template = loader.get_template("home.html")
        return HttpResponse(template.render())

注意:GET请求应该有副作用,因此构造 用户发出 GET 请求时的对象,不符合 HTTP 标准。因此,最好将其转换为 POST 请求。

【讨论】:

我试过了,但它不起作用。进行更改后是否必须进行迁移?但是,在进行该更改并运行迁移命令时,我看不到任何迁移所需。 @HarshPatel:不,这不需要迁移。您是否在返回 self.id 而不是 str(self.id) 的情况下制作了其他模型? 不,我没有在其他模型的任何地方使用过 str 。我在其他模型中也到处使用 self.id。 @HarshPatel:此外,您应该将 id 分配给 field_id 字段,或将对象分配给 ForeignKeyfield 字段,不要将两者混合。 对不起,我没有明白你的意思。能详细点吗?

以上是关于/writeReview/1 __str__ 处的 Django 模型 TypeError 返回非字符串(int 类型)的主要内容,如果未能解决你的问题,请参考以下文章

将 __m256i 寄存器转换为 uint64_t 位掩码,以便每个字节值处的值是输出中的设置位

对于模型的路径“_id”处的值,转换为 ObjectId 失败

CastError:路径“_id”处的值“”转换为 ObjectId 失败

__str__和__repr的区别

对于模型“Product”的路径“_id”处的值“ascendPrice”,Cast to ObjectId 失败是啥?

模型的路径“_id”处的值“”转换为 ObjectId 失败