简体   繁体   English

如何将Python对象转换为String?

[英]How to convert Python Object into String?

QuerySelectField is displaying the query correctly but its not saving in the database, it shows the following error while submitting. QuerySelectField正在正确显示查询,但未将其保存在数据库中,因此在提交时显示以下错误。

ProgrammingError: (ProgrammingError) can't adapt type 'Category' 'INSERT INTO articles (title, body, category, created) VALUES (%(title)s, %(body)s, %(category)s, %(created)s) RETURNING articles.id' {'category': <blog.models.Category object at 0x03A7E2D0>, 'body': u'Test', 'title': u'This is the New Post', 'created': datetime.datetime(2013, 10, 16, 14, 7, 23, 508000)}

在此处输入图片说明

When i enter the title and content and choose the category which is displayed by quering the results from category database and when trying to submit, it throws the above error. 当我输入标题和内容并通过从类别数据库查询结果来选择显示的类别时,并尝试提交时,将引发上述错误。

I know my the error is this line 我知道我的错误是这条线

{'category': <blog.models.Category object at 0x03A7E2D0>

How can i get it correct, where i am missing badly. 我如何正确纠正我严重失踪的地方。


Forms.py Forms.py

from models import DBSession
from models import Category
from wtforms import Form, TextField, TextAreaField, SubmitField, validators
from wtforms.ext.sqlalchemy.fields import QuerySelectField

def category_choice():
    return DBSession.query(Category)

class ArticleCreateForm(Form):
    title = TextField('Title', [validators.required(), validators.length(min=1,max=240)])
    body = TextAreaField('Content', [validators.required()])
    category = QuerySelectField('Category', query_factory=category_choice )
    submit = SubmitField()


class CategoryCreateForm(Form):
    name = TextField('Name', [validators.required(), validators.length(min=1,max=240)])
    description = TextAreaField('Description', [validators.required()])
    submit = SubmitField()

Views.py Views.py

@view_config(route_name='article_action', match_param='action=create', renderer='articles/create.jinja2')
def create(request):
    article = Article()
    category = Category()
    form = ArticleCreateForm(request.POST)
    if request.method == 'POST' and form.validate():
        form.populate_obj(article )
        DBSession.add(article, category)
        return HTTPFound(location=request.route_url('home'))
    return {'form':form, 'action':request.matchdict.get('create')}

Models.py Models.py

class Category(Base):
    __tablename__ = 'categories'
    id = Column(Integer, primary_key=True)
    name = Column(String(100), unique=True, nullable=False)
    description = Column(Text, nullable=False)

    def __unicode__(self):
        return self.name

class Article(Base):
    __tablename__ = 'articles'
    id = Column(Integer, primary_key=True)
    title = Column(String(255), unique=True, nullable=False)
    body =  Column(Text, nullable=False)
    category = Column(ForeignKey(Category.name), nullable=False)
    created = Column(DateTime, default=datetime.datetime.now)


    @property
    def slug(self):
        return urlify(self.title)

    @property
    def created_in_words(self):
        return time_ago_in_words(self.created)

Create.jinja2 Create.jinja2

{% extends 'base.jinja2' %}

{% block content %}
    <form action="{{ request.route_url('article_action', action='create') }}" method="post">
        {{ form.title.label }}
        {{ form.title }}<br/>

        {{ form.body.label }}
        {{ form.body }}<br/>

        {{ form.category.label }}
        {{ form.category }}<br/>

        {{ form.submit }}
    </form>
        <a href="{{ request.route_url('home') }}">Home</a>
{% endblock %}

Full Traceback 完整回溯

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\pyramid_debugtoolbar\panels\performance.py", line 69, in noresource_timer_handler
    result = handler(request)
  File "C:\Python27\lib\site-packages\pyramid\tweens.py", line 21, in excview_tween
    response = handler(request)
  File "C:\Python27\lib\site-packages\pyramid_tm\__init__.py", line 82, in tm_tween
    reraise(*exc_info)
  File "C:\Python27\lib\site-packages\pyramid_tm\__init__.py", line 70, in tm_tween
    manager.commit()
  File "C:\Python27\lib\site-packages\transaction\_manager.py", line 111, in commit
    return self.get().commit()
  File "C:\Python27\lib\site-packages\transaction\_transaction.py", line 280, in commit
    reraise(t, v, tb)
  File "C:\Python27\lib\site-packages\transaction\_transaction.py", line 271, in commit
    self._commitResources()
  File "C:\Python27\lib\site-packages\transaction\_transaction.py", line 417, in _commitResources
    reraise(t, v, tb)
  File "C:\Python27\lib\site-packages\transaction\_transaction.py", line 389, in _commitResources
    rm.tpc_begin(self)
  File "C:\Python27\lib\site-packages\zope\sqlalchemy\datamanager.py", line 90, in tpc_begin
    self.session.flush()
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 1818, in flush
    self._flush(objects)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 1936, in _flush
    transaction.rollback(_capture_exception=True)
  File "C:\Python27\lib\site-packages\sqlalchemy\util\langhelpers.py", line 58, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 1900, in _flush
    flush_context.execute()
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 372, in execute
    rec.execute(self)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 525, in execute
    uow
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\persistence.py", line 64, in save_obj
    table, insert)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\persistence.py", line 569, in _emit_insert_statements
    execute(statement, params)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 662, in execute
    params)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 761, in _execute_clauseelement
    compiled_sql, distilled_params
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 874, in _execute_context
    context)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1024, in _handle_dbapi_exception
    exc_info
  File "C:\Python27\lib\site-packages\sqlalchemy\util\compat.py", line 195, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 867, in _execute_context
    context)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\default.py", line 324, in do_execute
    cursor.execute(statement, parameters)
ProgrammingError: (ProgrammingError) can't adapt type 'Category' 'INSERT INTO articles (title, body, category, created) VALUES (%(title)s, %(body)s, %(category)s, %(created)s) RETURNING articles.id' {'category': <blog.models.Category object at 0x03A7E2D0>, 'body': u'Test', 'title': u'This is the New Post', 'created': datetime.datetime(2013, 10, 16, 14, 7, 23, 508000)}

Your problem lies here: 您的问题出在这里:

form.populate_obj(article)

This basically assigns the form field values to the database object's corresponding fields. 这基本上是将表单字段值分配给数据库对象的相应字段。 However, you are not using a SQLAlchemy relationship (you should!) so article.category needs to contain the name (why not ID?!) of the category. 但是,您没有使用SQLAlchemy relationship (应该这样做!),因此article.category需要包含类别的名称(为什么不是ID ?!)。 However, the QuerySelectField has the database object (ie a Category instance) as its value. 但是, QuerySelectField将数据库对象(即Category实例)作为其值。

You have three options; 您有三个选择; the third one is the preferred one: 第三个是首选的:

  • Use a normal SelectField with choices populated from the database 使用普通的SelectField以及从数据库中填充的choices
  • Don't use populate_obj but assign the category manually using 不要使用populate_obj而是使用手动分配类别

     article.category = form.category.data.name 
  • Rename the category column in Article to eg category_name and use a relationship() so Article.category does not contain the name but a Category object. Articlecategory列重命名为例如category_name并使用一个relationship()所以Article.category不包含名称,而是包含Category对象。

The category relationship in your Article model is not correct. 您的Article模型中的类别关系不正确。 It has two problems: 它有两个问题:

  1. you have not provided the data type for the column. 您尚未提供该列的数据类型。
  2. Article.category needs to be a relationship, not a column. Article.category必须是一个关系,而不是一个列。

If you modify your Article class to something like this things should improve: 如果将Article类修改为类似以下内容,则应该会改善:

class Article(Base):
    ...
    category_name = Column(String(100), ForeignKey(Category.name), nullable=False)
    category = relationship(Category)

If you do that SQLAlchemy will know that the category property must be a Category instance and will automatically load and save Category instances as needed. 如果这样做,SQLAlchemy将知道category属性必须是Category实例,并将根据需要自动加载和保存Category实例。

将关系添加到您的模型字段。

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

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