Having Problems Displaying followed users posts in Python Flask - python

So I have a problem with my project. I am trying to display the user's followings posts but nothing is displayed. I don't know what the problem is as no errors are being displayed. This is what I am using to help me to query followed posts (page 158)
This is where the posts should be displayed. This gives the user the option to show all posts or just followed posts
Nothing is being displayed though.
Here is the User class where I am defining followed posts:
The function followed_post() is supposed to display the users followed posts
#property
def followed_posts(self):
return Post.query.join(Follow, Follow.followed_id == Post.user_id).filter(Follow.follower_id == self.id)
In my main routes i have ;
#main.route('/all')
#login_required
def show_all():
resp = make_response(redirect(url_for('main.compscipost')))
resp.set_cookie('showed_followed', '' , max_age =
30*24*60*60)
return resp
#main.route('/followed')
#login_required
def show_followed():
resp = make_response(redirect(url_for('main.HomePage')))
resp.set_cookie('showed_followed', '1', max_age = 30*24*60*60)
return resp
and also in the blueprint =' main' routes.py, the function for my homepage is :
#main.route('/')
#main.route('/home')
def HomePage():
page = request.args.get('page', 1, type = int)
showed_followed = False
if current_user.is_authenticated:
showed_followed = bool(request.cookies.get('showed_followed', ''))
if showed_followed:
query= current_user.followed_posts
else:
query = Post.query
pagination =
query.order_by(Post.date_posted.desc()).paginate(page = page,
per_page = 5,
error_out = False)
posts = pagination.items
return render_template("HomePage.html", posts =posts,
showed_followed = showed_followed ,
pagination = pagination)
Finally for my homepage.html which I think is where the main problem is :
this is the homepage.html .
This is a pastebin of the html

That's because you're just building a query in your def followed_posts() property.
You should end it with .one() or .all() or first().
On a side note, if you're using SQLAlchemy take a look at hybrid properties. As regular Python properties will sometimes cause you problems when you're querying with instance and class attributes at the same time.

From what I can see, in your HomePage endpoint you're setting posts=pagination.items, and in your HTML you're looping through post.items as well.
Try this in your HTML:
{% for post in posts %}
# ...
{% endfor %}

Related

How to display username in multiple pages using flask?

I have encountered a problem of having the username not being shown on all the pages running under my flask application, it only runs at the home page because I return it from the login function. However, I don't know how could I get all the pages being called to have the username visible in all of them.
In the code attached, the def featured_books() doesn't return the username as it should be, instead it returns it as 1. How to solve this issue?
flask.py
#app.route('/')
# Gets correct username
#app.route('/index')
def home(post=1):
return render_template("index.html", username=post)
# Doesn't get the username
#app.route('/featured_books')
def featured_books(post=1):
return render_template("featured_books.html", username=post)
#app.route('/login')
def login(post=1):
if not session.get('logged_in'):
return render_template("login.html")
else:
return home(post)
#app.route('/login', methods=['POST'])
def do_login():
POST_USERNAME = str(request.form['username'])
POST_PASSWORD = str(request.form['password'])
secure_password = sha512_crypt.encrypt(POST_PASSWORD)
Session = sessionmaker(bind=engine)
s = Session()
query = s.query(User_reg).filter(User_reg.username.in_([POST_USERNAME]),
User_reg.password.in_([POST_PASSWORD]))
result = query.first()
if result:
session['logged_in'] = True
else:
flash('Wrong password!')
return login(POST_USERNAME)
I was working on the same thing and came across your question.
Have you figured it out?
Some suggest using Flask-Login extension to handle session management. Because I'm working on a simple app I decided to put the user name into a session cookie. Then can just grab it from the session on another page. Seemed like the path of least resistance, though, may not be the best choice.
Storing it in route.py
session['user_name'] = user.firstname + ' ' + user.lastname
Grabbing it from an html page
<h3> Welcome, {{session['user_name']}}! </h3>

What should I use to get the title and post to show?

I'm working on an assignment using python, flask-env, and my sql and I am stuck on trying to get the blog title and blog post to show. I can only get the name of the person to show(which I need but the other stuff is important as well).
If I leave the template with just "indiv_post" for both fields, it shows "None", but if I put anything other that or anything with it, nothing but the author name shows.
in my main.py:
#app.route('/blog', methods=['POST', 'GET'])
def blog():
owner = User.query.filter_by(username=session['username']).first()
if request.method == 'POST':
blog_name = request.form('blog')
new_blog = Blog(blog_name, owner)
#post_title = request.form('blog_title')
#post_entry = request.form('your_thoughts')
db.session.add(new_blog)
db.session.commit()
post_id = request.args.get('id')
indiv_post = Blog.query.get('post_id')
user_id = request.args.get('owner_id')
posts = Blog.query.filter_by(owner_id=user_id)
blog = Blog.query.filter_by(owner_id=user_id)
return render_template('indiv_post.html', owner_id=owner, blog=blog, post=post_id, indiv_post=indiv_post)
in my template(indiv_post.html):
<h1>My Posts</h1>
<h2>{{posts}}</h2>
<p>{{indiv_post}}</p>
<p class="byline">Written by {{session['username']}}</p>
<hr>
I expect the output to be show:
Blog Title
Blog post
written by: user
But I'm getting:
None
None
written by: user

How to remove session variable in a template after it's job is done in django

I have a app called dashboard which is where I redirect all logged in users with an option to add articles by the user.
After the user hits Submit button in the form, the data is sent to /dashboard/article/save URL via POST and after the data is stored, the view returns HttpResponseRedirect to show_dashboard which renders dashboard.html with a session variable result.
In the dashboard template file, I have added a notify.js code to show acknowledgements to user. The problem is if this session var is defined, everytime the dashboard page is showed, the notification is triggered EVEN if the user didn't add an article.
(I'm new to using web frameworks so I do not know how this all works properly)
Some code:
dashboard/models.py:
class Article(models.Model):
id = models.IntegerField(primary_key=True)
ar_title = models.CharField(max_length=25)
ar_data = models.CharField(max_length=500)
user = models.ForeignKey(User,on_delete=models.CASCADE)
def getArticleTitle(self):
return self.title
def getArticleData(self):
return self.title
def getArticleAuthor(self):
return self.user
dashboard/urls.py:
urlpatterns = [
url(r'^$', views.show_dashboard,name='home_dashboard'),
url(r'^profile/save/', views.save_profile,name="save_profile"),
url(r'^newsfeed/', views.get_newsfeed,name="newsfeed",),
url(r'^profile/', views.show_profile,name="show_profile"),
url(r'^article/save/', views.add_new_article,name="add_new_article"),
]
dashboard/views.py:
#login_required
def show_dashboard(request):
return render(request,'dashboard/dashboard.html',{'form':NewArticleForm()})
def add_new_article(request):
if(request.method == 'POST'):
ar_title= request.POST['ar_title']
ar_data = request.POST['ar_data']
user = request.user
form = NewArticleForm(request.POST)
if(form.is_valid()):
Article.objects.create(ar_title=ar_title,ar_data=ar_data,user=user)
request.session["result"] = "add_article_OK"
return HttpResponseRedirect(reverse('home_dashboard'))
dashboard.html:
{% ifequal request.session.result 'add_article_OK' %}
<script>
$.notify("New article added successfully",
{position:"bottom right","className":"success","autoHide":"yes","autoHideDelay":"3000"});
</script>
{% endifequal %}
Now, how do I remove this session value after it has displayed the message? I know del request.session['result'] can be issued but where can I put it in this heirarchy of moves?
Do it in the show_dashboard view.
Instead of getting the value from the session in the template, pop it in the view and pass it to the template; that way you take care of getting and clearing it in one go.
#login_required
def show_dashboard(request):
context = {
'form': NewArticleForm(),
'result': request.session.pop('result', None)
}
return render(request,'dashboard/dashboard.html',context)
...
{% ifequal result 'add_article_OK' %}

Edit Post Using same form in Flask/SQLAlchemy

I am new to programming and am working on creating a simple blog with posts and comments. I am having trouble creating an editpost feature using the same form template to add posts. This is my data model for add post:
#app.route("/addpost", methods=['POST'])
def addpost():
title = request.form['title']
text = request.form['content']
post = Post(title = title, body = content)
db.session.add(post)
db.session.commit()
return redirect(url_for("posts"))
This is currently what I have but I am receiving a Bad Proxy Request.
#app.route("/editpost/<int:id>", methods=['GET', 'POST'])
def editpost(id):
title = request.form['title']
text = request.form['content']
post = db.session.query(Post).filter(Post.id==id).first()
post.title = title
post.body = content
db.session.commit()
return redirect(url_for("post", id=id))
Any help is appreciated. Thanks!
You have an endpoint, editpost, that supports both GET and POST requests. The code inside the endpoint, however, assumes a valid POST request. You are receiving a bad request error because of
title = request.form['title']
text = request.form['content']
The first line is where you get the error, but either line would cause it. request.form is populated by the post data in a POST request. When someone submits a GET request (you probably offer a link to the edit page, resulting in the GET), request.form does not contain either of these keys. Flask traps the KeyError that is raised and replaces it with a BadRequest.
There are two things you'll have to do to prevent this from happening. First, you'll only want to do this when the request is a POST. Assuming you want to use the same endpoint and URL to both display the edit form and perform the update, you'll want to include your code inside
if request.method == 'POST':
Next, because you probably want to display the form and some error messages when fields are missing, you'll want to be a bit more defensive when accessing the values.
title = request.form.get('title')
text = request.form.get('content')
Putting it all together:
#app.route('/editpost/<int:id>', methods=['GET', 'POST'])
def editpost(id):
post = db.session.query(Post).filter(Post.id==id).first()
if request.method == 'POST':
title = request.form['title']
text = request.form['content']
post.title = title
post.body = content
db.session.commit()
return redirect(url_for('post', id=id))
else:
return render_template('something.html', post=post)

Django: get a NoReverseMatch while rendering error

I seem to be getting a Caught NoReverseMatch error. I am not so sure what is causing the problem. Have a look at the full error.
Caught NoReverseMatch while rendering: Reverse for 'mmc.views.edit_note' with arguments '(1L, '')' and keyword arguments '{}' not found.
On my get_client page. I have a link to the edit note page. I am assuming the problem might be here in my template. I think the note.pk is the problem.
Edit Note
Here is also some more information which could help.
urls.py
(r'^clients/(?P<client_id>\d+)/$', views.get_client),
(r'^clients/notes/(?P<client_id>\d+)(?P<note_id>\d+)$', views.edit_notes),
views.py
#login_required
def edit_notes(request, client_id = 0, note_id = 0):
client = None
note = None
try:
client = models.Client.objects.get(pk = client_id)
note = models.Note.objects.get(pk = note_id)
except:
return HttpResponseNotFound()
if request.method == 'POST':
form = forms.NoteForm(request.POST, instance=note)
if form.is_valid():
note = form.save(commit=False)
note.user = request.user
note.client = client
note.save(True)
request.user.message_set.create(message = "Note is successfully added.")
return HttpResponse("<script language=\"javascript\" type=\"text/javascript\">window.opener.location = window.opener.location; window.close();</script>")
else:
form = forms.NoteForm(instance=note)
return render_to_response('note_form.html', {'form':form, 'client':client, 'note':note}, context_instance = RequestContext(request))
*EDIT: * Seem to have corrected most of it Here are some changes I have made.
Template
{% for note in notes %}
Edit Note
{% endfor%}
urls.py
(r'^clients/notes/(?P<client_id>\d+)/(?P<note_id>\d+)/$', views.edit_note)
Now the only problem is it displays all of the links to each edit form notes for an individual client. I only want the link for the latest note and only the latest note. Is there a possible way?
The client.pk and note.pk are empty values, so they don't match the regex.
(r'^clients/(?P<client_id>\d+)/$', views.get_client) should be something like url(r'^clients/(?P<client_id>\d+)/$', views.get_client, name='MY_URL_NAME') then called with {% url MY_URL_NAME client.pk %}
and import url from django.conf.urls.defaults

Categories