-
-
Save TheMuellenator/b4e21f77c04afcac85a7ec2a262ea0d7 to your computer and use it in GitHub Desktop.
## MORE CODE ABOVE | |
class User(UserMixin, db.Model): | |
__tablename__ = "users" | |
id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
email: Mapped[str] = mapped_column(String(100), unique=True) | |
password: Mapped[str] = mapped_column(String(100)) | |
name: Mapped[str] = mapped_column(String(100)) | |
#This will act like a List of BlogPost objects attached to each User. | |
#The "author" refers to the author property in the BlogPost class. | |
posts = relationship("BlogPost", back_populates="author") | |
class BlogPost(db.Model): | |
__tablename__ = "blog_posts" | |
id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
# Create Foreign Key, "users.id" the users refers to the tablename of User. | |
author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id")) | |
# Create reference to the User object. The "posts" refers to the posts property in the User class. | |
author = relationship("User", back_populates="posts") | |
title: Mapped[str] = mapped_column(String(250), unique=True, nullable=False) | |
subtitle: Mapped[str] = mapped_column(String(250), nullable=False) | |
date: Mapped[str] = mapped_column(String(250), nullable=False) | |
body: Mapped[str] = mapped_column(Text, nullable=False) | |
img_url: Mapped[str] = mapped_column(String(250), nullable=False) | |
## MORE CODE BELOW |
``> ![image](https://private-user-images.githubusercontent.com/95513071/307592162-050dee4c-17c4-4d56-b9de-3997eb2f1d5a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAzMzU3OTcsIm5iZiI6MTcyMDMzNTQ5NywicGF0aCI6Ii85NTUxMzA3MS8zMDc1OTIxNjItMDUwZGVlNGMtMTdjNC00ZDU2LWI5ZGUtMzk5N2ViMmYxZDVhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzA3VDA2NTgxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTkyNWIyY2VlYzYwZTk0NGY3YTY0YjgwODEyZmI0MTA5NTlhMWY4OGVhMjNkMjFjYTRmNjFlMDM5MzgyZmY4MGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.2s98MkAVyM9iugXjyIxNU-Spzz9hhagOC1hu4UFUHlA) Add the user first then restart server it works for me
Just remove the parameters from Users() and add a method called add_details in User class which assigns value to email, password, name
class User(UserMixin, db.Model):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
password: Mapped[str] = mapped_column(String(250), nullable=False)
name: Mapped[str] = mapped_column(String(250), nullable=False)
posts = relationship("BlogPost", back_populates="author")
def add_details(self, email, password, name):
self.email = email
self.password = password
self.name = name
new_user = User()
new_user.add_details(
email=form.email.data,
password=hashed_password,
name=form.name.data
)
for 404 I just restarted chrome.
class Users(UserMixin, db.Model):
__tablename__ = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
password: Mapped[str] = mapped_column(String(255), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
posts: Mapped[list[BlogPost]] = relationship("BlogPost", back_populates="author")
class BlogPost(db.Model):
__tablename__ = "blog_posts"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
title: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
subtitle: Mapped[str] = mapped_column(String(255), nullable=False)
date: Mapped[str] = mapped_column(String(255), nullable=False)
body: Mapped[str] = mapped_column(Text, nullable=False)
img_url: Mapped[str] = mapped_column(String(255), nullable=False)
author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id"))
author: Mapped[Users] = relationship("Users", back_populates="posts")
This is my piece of code. Please check anyone is it good or not? If anyone wants to modify my code you are free to do that...
Ok, got it to work.
First comment out the login manager code. We don't have any users in this new database that's why we are getting 404 status code.
# login_manager = LoginManager() # login_manager.init_app(app) # @login_manager.user_loader # def load_user(user_id): # return db.get_or_404(Users, user_id)Next we have to find all the "current_user" code portions in our templates, mostly in index and header html files and comment those out too. e.g.
{# {% if current_user.id == 1 %} #} <div class="d-flex justify-content-end mb-4"> <a class="btn btn-primary float-right" href="{{url_for('add_new_post')}}" >Create New Post</a > </div> {# {% endif %} #}
After that create your admin user like before and then uncomment the code :)
Thank you for this man.
Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?
@vishalkirtisharma I also got a 404 error coming from here:
# create a user loader callback @login_manager.user_loader def load_user(user_id): return db.get_or_404(User, user_id)
I solved it by clearing the cache of my browser first. I think it's because the browser remembered who was logged in, but then off course could not find back that user because you had just deleted the .db
Yes, you're right. I opened a 'inplrivate window' and it works fine for me.
I ended up stock on this for some time until I realized clear cache fixes it
yeah, clear cache fixed it for me too. thank you.
Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?
I'm having this same issue. I cannot figure out how to fix it. Currently checking stack overflow for a solution.
I get this error
.NoReferencedTableError: Foreign key associated with column 'blog_posts.author_id' could not find table 'users' with which to generate a foreign key to target column 'id'
Here is my code
class User(UserMixin, db.Model):
tablename = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(100), unique= True, nullable=False)
password: Mapped[str] = mapped_column(String(100), nullable=False)
name: Mapped[str] = mapped_column(String(100))
posts: Mapped[list['BlogPost']] = relationship("BlogPost", back_populates="author")
class BlogPost(db.Model):
tablename = "blog_posts"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id"))
author:Mapped[User] = relationship("Users", back_populates="posts")
title: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
subtitle: Mapped[str] = mapped_column(String(250), nullable=False)
date: Mapped[str] = mapped_column(String(250), nullable=False)
body: Mapped[str] = mapped_column(Text, nullable=False)
img_url: Mapped[str] = mapped_column(String(250), nullable=False)
The solution code is no longer working and need Mapped[] for all the lines with the "relationship"
I was getting the following error:
in
class User(UserMixin, db.Model): # parent table
sqlalchemy.exc.ArgumentError: Type annotation for "User.posts" can't be correctly interpreted for Annotated Declarative Table form. ORM annotations should normally make use of the `Mapped[] generic type, or other ORM-compatible generic type, as a container for the actual type, which indicates the intent that the attribute is mapped. Class variables that are not intended to be mapped by the ORM should use ClassVar[]. To allow Annotated Declarative to disregard legacy annotations which don't use Mapped[] to pass, set "allow_unmapped = True" on the class or a superclass this class.
So I had to map the "posts" and "author" that had relationship. Here are these two lines:
In class User(UserMixin, db.Model):
posts: Mapped[list["BlogPost"]] = relationship("BlogPost", back_populates="author")
In class BlogPost(db.Model):
author: Mapped["User"] = relationship("User", back_populates="posts")
Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?
I'm having this same issue. I cannot figure out how to fix it. Currently checking stack overflow for a solution.
As we have now added the relationship between tabels, the author is no longer a string but an object.
find the string
current_user.name
replace them with object
current_user
ps. There should be two current_user.name to be replaced.
Ok, got it to work.
First comment out the login manager code. We don't have any users in this new database that's why we are getting 404 status code.
# login_manager = LoginManager() # login_manager.init_app(app) # @login_manager.user_loader # def load_user(user_id): # return db.get_or_404(Users, user_id)Next we have to find all the "current_user" code portions in our templates, mostly in index and header html files and comment those out too. e.g.
{# {% if current_user.id == 1 %} #} <div class="d-flex justify-content-end mb-4"> <a class="btn btn-primary float-right" href="{{url_for('add_new_post')}}" >Create New Post</a > </div> {# {% endif %} #}
After that create your admin user like before and then uncomment the code :)
Thx, it works. It takes a lot of time to comment all current_user and other jinja variables, but it done.
I ended up stock on this for some time until I realized clear cache fixes it