Search code examples
pythongoogle-app-engineweb-applicationsjinja2webapp2

BadValueError: Property text is required


I've done a lot of research trying to solve this problem myself but I am running up short of a solution. If anyone can give me any pointer or help I would really appreciate it.

I am creating a blog that has basic blog functionality such as; likes, dislikes, posts, comments, multiple users, CRUD functions etc. I have so far been able to overcome most of my problems and I am near the completion of this project.

The last bit of trouble I am having is with my Edit Comment functionality, I can delete a comment just fine but if I try to update a comment I got the following error:

ERROR    2017-03-08 14:26:21,907 wsgi.py:279] 
Traceback (most recent call last):
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 267, in Handle
    result = handler(dict(self._environ), self._StartResponse)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 1519, in __call__
    response = self._internal_error(e)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 547, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.3/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/home/crow/UdacityProjects/blog/blog.py", line 424, in post
    comment.text = self.request.get('comment_text')
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/google/appengine/ext/db/__init__.py", line 617, in __set__
    value = self.validate(value)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/google/appengine/ext/db/__init__.py", line 2810, in validate
    value = super(UnindexedProperty, self).validate(value)
  File "/home/crow/Downloads/google-cloud-sdk/platform/google_appengine/google/appengine/ext/db/__init__.py", line 644, in validate
    raise BadValueError('Property %s is required' % self.name)
BadValueError: Property text is required

Now I am not exactly sure why this is happening, I looked up the solutions that others were finding for similar problems and none seemed to apply to my situation. Here is my relevant code for reference:

EditComment(BlogHandler)

class EditComment(BlogHandler):

    def get(self, post_id, comment_id):
        post = Post.get_by_id(int(post_id), parent=blog_key())
        comment = Comment.get_by_id(int(comment_id))
        if comment:
            if comment.user.name == self.user.name:
                self.render("editcomment.html", comment_text=comment.text)
            else:
                error = "You may only edit your own comments"
                self.render("editcomment.html", edit_error=error)
        else:
            error = "This comment no longer exists"
            self.render("editcomment.html", edit_error=error)

    def post(self, post_id, comment_id):
        if self.request.get("update_comment"):
            comment = Comment.get_by_id(int(comment_id))
            if comment.user.name == self.user.name:
                comment.text = self.request.get('comment_text')
                comment.put()
                time.sleep(0.1)
                self.redirect('/post/%s' % str(post_id))
            else:
                error = "you may only edit your own comments"
                self.render(
                    "editcomment.html",
                    comment_text=comment.text,
                    edit_error=error)
        elif self.request.get("cancel"):
            self.redirect('/post/%s' % str(post_id))

Comment(db.model)

class Comment(db.Model):
    user = db.ReferenceProperty(User, required=True)
    post = db.ReferenceProperty(Post, required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    text = db.TextProperty(required=True)

    @classmethod
    def cdb_blog_id(cls, blog_id):
        c = Comment.all().filter('post =', blog_id)
        return c.count()

    @classmethod
    def adb_blog_id(cls, blog_id):
        c = Comment.all().filter('post =', blog_id).order('created')
        return c

editcomment.html

{% extends "base.html" %}
{% block content %}
  <div class="twelve columns">
    <h3>Edit Comment</h3>
    <hr>
      <div class="row">
        <div class="twelve columns">
        <form method="post">
           <label>
             <textarea class="u-full-width" name="text" id="texta2">{{comment_text}}</textarea>
           </label>
           <div class="error">{{edit_error}}</div>
           <input type="submit" class="button" name="update_comment" value="Update">
           <input type="submit" class="button" name="cancel" value="Cancel">
         </form>
         </div>
       </div>
     </div>
{% endblock %}

Now the traceback does not point to the area in my code that is causing the issue so I will provide the relevant lines of the __inti__.py file here:

Line 617

  def __set__(self, model_instance, value):
    """Sets the value for this property on the given model instance.

    See http://docs.python.org/ref/descriptors.html for a description of
    the arguments to this class and what they mean.
    """
    value = self.validate(value)
    setattr(model_instance, self._attr_name(), value)

Line 2810

raise BadValueError('Property %s must be convertible '
                            'to a %s instance (%s)' %
                            (self.name, self.data_type.__name__, err))
    value = super(UnindexedProperty, self).validate(value)
    if value is not None and not isinstance(value, self.data_type):
      raise BadValueError('Property %s must be a %s instance' %
                          (self.name, self.data_type.__name__))
    return value

Line 644

if self.empty(value):
      if self.required:
        raise BadValueError('Property %s is required' % self.name)

I'm not sure what I'm doing wrong here, and if anyone would be able to offer me any kind of advice I would be very grateful. Thanks again


Solution

  • The error indicates that the value you get from self.request.get('comment_text') and pass to comment.text is invalid - None probably.

    The check is done because the text property has the option required set to True in the Comment model.

    So check that you properly pass the 'comment_text' request parameter (or its value) around.

    Maybe you need name="comment_text" in the following line from editcomment.html?

    <textarea class="u-full-width" name="text" id="texta2">{{comment_text}}</textarea>