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
Related
I try to build a flask site with a very simple dictionary. A user can save words which are stored in a simple sqlite database. All that works fine, but if I try to implement a simple test on the vocabulary I canĀ“t get consistent data from the database. The site is called, and after validate_on_submit it is relaoded so my choice from the database is a new one. Sorry for the bad description, may be it is gettinger clearer if I show you the code. I followed the CoreySchaefer Tutorials and the structur, so
# forms.py
# ...
class VocTestForm(FlaskForm):
german = StringField('Deutsch', validators=[DataRequired()])
submit = SubmitField('Check')
# models.py
# ...
class Dictionary(db.Model):
id = db.Column(db.Integer, primary_key=True)
engl = db.Column(db.String(120), unique=True, nullable=False)
german = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"{self.engl} {self.german}"
# voc_test.html
{% extends "base_layout.html" %}
{% import "bootstrap/wtf.html" as wtf%}
{% block content %}
<h1>{{check_word.engl}}</h1>
{{ wtf.quick_form(form) }}
{% endblock %}
# routes.py
# ...
#app.route('/voc_test', methods=['GET', 'POST'])
def voc_test():
form = VocTestForm()
content = Dictionary.query.all()
check_word = random.choice(content)
if form.validate_on_submit():
if str(form.german.data) == str(check_word.german):
flash(f'Correct', 'success')
return redirect(url_for('voc_test'))
else:
flash(f'wrong', 'danger')
form.german = " "
return render_template('voc_test.html', form=form, check_word=check_word
The last function is not working. If I compare the String from the form with the String from the database the random.choice has already chosen a new word. How can I prevent this?
Thanks for the help
Steffen
If I've read what you're trying to do right, you could use the random library to generate a number. Then pull the item at that index from the dictionary.
EDIT
Here is my test:
def test_admin_sees_unpublished_questions(self):
"""
Logged-in admin users see unpublished questions on the index page.
"""
# create admin user and log her in
password = 'password'
my_admin = User.objects.create_superuser('myuser', 'myemail#test.com', password)
user = authenticate(username="myuser", password="password")
if user is not None:
print(user.username)
else:
print('Not found!')
self.client.login(username=my_admin.username, password=password)
#create future question and check she can see it
create_question(question_text="Unpublished question.", days=5)
response = self.client.get(reverse('polls:index'))
self.assertContains('Please review these unpublished questions:')
self.assertEqual(response.context["user"], user)
self.assertQuerysetEqual(
response.context['unpublished_question_list'],
['<Question: Unpublished question.>']
)
It's a bit messy. There are a few lines checking if there is a user in context which all appear to show response.context["user"] is there.
Here is my view:
class IndexView(generic.ListView):
template_name = 'polls/index.html'
def get_queryset(self):
"""
Return the last five published questions (not including those set to be
published in the future).
"""
queryset = Question.objects.filter(
pub_date__lte=timezone.now()
).exclude(
#question without choices
choice=None
).order_by('-pub_date')[:5]
return queryset
def get_context_data(self, **kwargs):
"""
Override get_context_data to add another variable to the context.
"""
context = super(IndexView, self).get_context_data(**kwargs)
context['unpublished_question_list'] = Question.objects.filter(pub_date__gte=timezone.now())
print(context)
return context
I am writing tests for the django polls app tutorial.
I want to write a test which which logs in a user, creates an instance of the question model with a publish date in the future, and ensures that this logged in user can see this question.
I've tried using
self.assertContains('Please review these unpublished questions: ')
in the test method because my template looks like this:
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}. Please review these unpublished questions: </p>
{% if unpublished_question_list %} etc
but even though
self.assertEqual(response.context["user"], user)
passes testing after
self.client.login(username=my_admin.username, password=password)
my template doesn't seem to be rendering properly to the test client.
Some help would be much appreciated!
AssertionError: False is not true : Couldn't find 'Please review these unpublished questions: ' in response
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 %}
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' %}
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)