'BlogPost'对象没有属性'post_id'+无法显示与blog_validated_id相同的blog_post_id的注释 [英] 'BlogPost' object has no attribute 'post_id' + Can't display comments that have blog_post_id the same as blog_validated_id

查看:96
本文介绍了'BlogPost'对象没有属性'post_id'+无法显示与blog_validated_id相同的blog_post_id的注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个BlogPost模型(可以正常工作),然后创建了一个BlogInfo模型,该模型的外键变量与前一个变量相同.

I created a BlogPost model(working fine) and then a BlogInfo model that has a foreign key variable to the previous one.

我已成功存储了基于我的BlogInfo模型创建的表单中的数据,但是刷新代码后无法显示它们.例如,我有一个博客,其blog_validated_id为46.然后,当用户看到该博客时,他们可以单击一个按钮,并使用我的Blog Info模型在表单上发表评论(该表单将具有一个模型,该模型存储名为blog_post_id的列那将是46).

I successfully stored data from the form I created based on my BlogInfo model but can't show them after refreshing the codes. For example, I have a blog that has its blog_validated_id as 46. Then when the users see that blog, they can click a button, comment on a form using my Blog Info model (that form will have a model that stores a column called blog_post_id that will be 46).

现在,在用户发表评论后,我希望将他们重定向到相同的blog_page,除了所有博客评论的blog_post_id为46.

Now, after the users commented, I want them to be redirected to that same blog_page, except that there will be all the blog comments that have blog_post_id as 46.

以上两段是我想要实现的理想选择.但是,我遇到两个问题:

-1st

一旦我评论并提交博客信息评论表单(以下代码中的form2),就会出现此错误: AttributeError:'BlogPost'对象没有属性'post_id'这些代码位于我的BlogPost模型的末尾(与下面的BlogInfo模型一起显示):

Once I commented and submit the blog info comment form (form2 in the codes below), I get this error: AttributeError: 'BlogPost' object has no attribute 'post_id' My traceback then end at these codes, which is at the end of my BlogPost model(which is shown together with BlogInfo model down below):

    def __repr__(self):
        return f"Post ID: {self.post_id} -- Date:{self.date}---{self.problem_name}"

BlogPost和BlogInfo模型:

BlogPost and BlogInfo models:

class BlogPost(db.Model):
    __tablename__ = 'blog_post'
    users = db.relationship(User)

    blog_id = db.Column(db.Integer, primary_key=True)

    user_id = db.Column(db.Integer,db.ForeignKey('users.id'), nullable=False) #users.id  is taken from the tablename(users) and id in its table


    bloginfos2 = db.relationship('BlogInfo', backref="comment2", lazy=True)

    def __init__(self, user_id):

        self.user_id = user_id

    def __repr__(self):
        return f"Post ID: {self.post_id}"


class BlogInfo(db.Model):

    __tablename__ = 'blog_info'

    users=db.relationship(User)
    blog_post=db.relationship(BlogPost)

    blog_info_id = db.Column(db.Integer, primary_key=True)
    blog_post_id = db.Column(db.Integer, db.ForeignKey('blog_post.blog_id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    text = db.Column(db.Text, nullable=False)

    def __init__(self, blog_post_id, user_id, text):
        self.blog_post_id = blog_post_id
        self.user_id = user_id
        self.text = text

    def __repr__(self):
        return f"Blog info ID:{self.blog_info_id}--Blog id:{self.blog_post_id} -- Date:{self.date} -- {self.text}"

博客信息评论表单(用户评论的表单):

Blog Info comment form(the one that the users commented):

{% for post2 in comment_blogs.items %}
        <p><small class="">Posted on:{{ post2.date.strftime('%Y-%m-%d') }}</small></p>
          <p class="card-text ml-5">{{ post2.text }}</p>
    {% endfor %}

我的views.py:

My views.py:

@blog_posts.route('/<int:blog_validated_id>', methods=['GET', 'POST']) 
def blog_view(blog_validated_id):
    blog_view = BlogPost.query.get_or_404(blog_validated_id)

    print(blog_validated_id)

    form2=BlogInfoForm()

    if form2.validate_on_submit():

        blog_comment_validated = BlogInfo(text=form2.text.data,
                                          user_id=current_user.id,
                                          blog_post_id=blog_validated_id)
        db.session.add(blog_comment_validated)
        db.session.commit()
        flash("Blog's comment added")

        page = request.args.get('page', 1, type=int)
        comment_blogs1 = BlogInfo.query.filter(BlogInfo.blog_post_id.ilike(blog_validated_id)).order_by(BlogInfo.date.desc())
        comment_blogs = comment_blogs1.paginate(page=page,per_page=3)

        return redirect(url_for('blog_posts.blog_view', 
                           post=blog_view,
                           form2=form2,comment_blogs=comment_blogs, comment_text=blog_comment_validated.text, blog_validated_id=blog_validated_id))


    page = request.args.get('page', 1, type=int)
    comment_blogs = BlogInfo.query.order_by(BlogInfo.date.desc()).paginate(page=page, per_page=3)
    return render_template('blog_view.html', 
                           post=blog_view,
                          form2=form2, comment_blogs=comment_blogs, blog_validated_id=blog_validated_id)

如果您想知道我是如何获得blog_validated_id的,请看看我的第二个问题(它将很快变得直截了当)

If you wonder how I got blog_validated_id, please look at my 2st problem (it will be fast and straightaway)

第二名:

我认为上面的代码(现在在下面引用)不起作用.重定向url_for(blog_posts.blog_view)后,我的html文件仍显示所有博客信息注释,这些博客信息的blog_post_id与blog_validated_id不同.我认为我的python代码没有保存blog_validated_id:

I think that the codes above (which is now referenced below) is not working. After I redirect url_for (blog_posts.blog_view), my html file still show all the blog info comments that has blog_post_id different to blog_validated_id .I think that my python codes is not saving blog_validated_id:

 comment_blogs1 = BlogInfo.query.filter(BlogInfo.blog_post_id.ilike(blog_validated_id)).order_by(BlogInfo.date.desc())

非常重要的是,blog_validated_id是我从HTML文件传递到上述python的blog_posts.blog查看代码的变量.

Very importantly, blog_validated_id is a variable I passed from a HTML file to the python's blog_posts.blog view codes above.

通往blog_posts.blog的HTML文件查看python代码:

The HTML file that leads to blog_posts.blog view python codes:

{% for post in many_posts.items%}
<a href="{{ url_for('blog_posts.blog_view', blog_validated_id=post.blog_id) }}">Readmore</a>
{% endfor %}

上面的many_posts变量是所有博客,而blog_validated_id是每个个人博客的ID.

The many_posts variable above is all the blogs and blog_validated_id is the id of each individuals blog.

我是编码方面的初学者,我正在努力解决上述2个问题.如果您能帮助我,我将不胜感激.

I'm a beginner in coding and I'm struggling with the 2 problems above. I would greatly appreciate it if you could help me.

谢谢.

推荐答案

在类 BlogPost 中,您使用 __ repr __ 编写:

        return f"Post ID: {self.post_id} -- Date:{self.date}---{self.problem_name}"

这不是吗要么

        return f"Post ID: {self.pk} -- Date:{self.date}---{self.problem_name}"

        return f"Post ID: {self.blog_id} -- Date:{self.date}---{self.problem_name}"

其他评论1 :

与我通常使用的方式相比,声明主键和外键的方式有些不同.(这可能不是造成您问题的原因,但在我看来,这会使代码变得更复杂,以至于我看不懂.)

The way you declare primary keys and foreign keys is a little unusual compared to the way that I'm normally doing it. (It's probably not the cause of your issue, but it makes in my opinion the code more complicated to read for a benefice, that I don't understand.

如果您创建模型,则Django会自动添加一个主键,并将其命名为 id .我看不出要更改此行为的原因.使用Django的人已经习惯了 Model.id 是主键的事实.他们甚至不必担心模型的声明.如果您更改其名称,那么人们只有在查看您的类定义后才能理解.因此,我建议不要显式声明主键.然后删除

if you create a model then Django automatically adds a primary key and calls it id. I don't see a reason to change this behavior. People using Django are used to the fact, that Model.id is the primary key. They don't even have to kook at the declaration of your model. If you change its name, people don't understand until they look at your class definition. So I'd suggest to not explicitly declare a primary key. and just remove

blog_id = db.Column(db.Integer, primary_key=True)

来自 BlogPost

blog_info_id = db.Column(db.Integer, primary_key=True)

来自 BlogInfo

如果您这样做是因为您使用的是早于Django项目的数据库,那么我理解.尽管我在类似的情况下以Django方式声明了一个模型(让django也决定了表名),然后将数据从原始表复制到了新表中.(如果您想让Django和您的旧软件访问相同的表,那当然就行不通了

If you do this because you work with a database that pre-dates your Django project, then I understand. Though I in a similar situation declared a model the Django way (and let django also decide the table name) and copied the data from original tables into the new ones. (This doesn't work of course if you want Django and your old software access the same tables)

要引用模型自己的主键,只需编写 self.pk 或(如果您未明确声明主键 self.id ),(应该是 self.id 更快. self.pk 会更干净一点,因为如果显式声明了主键,它也可以工作.请查看Django查询-id vs pk 以形成您自己的观点

To make a reference to a models own primary key just write self.pk or (if you don't explicitly declare a primary key self.id) (self.id is supposed to be faster. self.pk is a little cleaner as it works also if a primary key has been declared explicitly. Look at Django queries - id vs pk to form your own opinion)

其他评论2 如果按照教程中显示的方式声明外键,则只需编写即可.

Other comments 2 If you declare Foreign keys the way it is shown in the tutorials, then you would just write.

from django.db import models
class BlogInfo(models.Model):
    blog_post = models.ForeignKey(
    'BlogPost', 
    on_delete=models.CASCADE,  # change this to your desired behaviour 
    null=True)

您会注意到两件事,它仅称为blog_post而不是blog_post_id.因此,在python代码中,如果您有BlogInfo条目(例如 blog_info = BlogInfo.objects.all()[0] )

You notice two things It's just called blog_post and not blog_post_id. So in python code if you have a BlogInfo entry (e.g. blog_info = BlogInfo.objects.all()[0])

然后,您只需编写 blog_info.blog_post blog_post,并且您有一个类型为 BlogPost 的实例如果您确实需要ID,只需输入 blog_info.blog_post.id

Then you just write blog_info.blog_post blog_post and you have an instance of type BlogPost If you really want the id, just type blog_info.blog_post.id

这当然会改变您的查询代替

It would of course change your queries instead of

BlogInfo.objects.get(blog_post_id=47)

你必须写

BlogInfo.objects.get(blog_post_id=47)  # double _ between blog_post and id

BlogInfo.objects.get(blog_post_pk=47)  # double _ between blog_post and pk

这篇关于'BlogPost'对象没有属性'post_id'+无法显示与blog_validated_id相同的blog_post_id的注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆