Add a Post
Once a user has successfully logged in or registered, they’re redirected to the / view, the home page. When session.username is not None, a form is displayed that allows the user to share a post. This form sends a POST request with the title, text, and tags of the post to the /add_post/<username> view, where <username> is replaced with the logged-in-user’s username. In views.py, this view is defined by the following:
@app.route('/add_post', methods=['POST'])
def add_post():
title = request.form['title']
tags = request.form['tags']
text = request.form['text']
if not title:
flash('You must give your post a title.')
elif not tags:
flash('You must give your post at least one tag.')
elif not text:
flash('You must give your post a text body.')
else:
User(session['username']).add_post(title, tags, text)
return redirect(url_for('index'))
The title, text, and tags that were sent with the POST request are accessed and checked to make sure they aren’t empty. If it all checks out, the User.add_post() method is called with title, text, and tags as arguments. The add_post() method is defined in the User class like so:
class User:
...
def add_post(self, title, tags, text):
user = self.find()
post = Node(
"Post",
id=str(uuid.uuid4()),
title=title,
text=text,
timestamp=timestamp(),
date=date()
)
rel = Relationship(user, "PUBLISHED", post)
graph.create(rel)
tags = [x.strip() for x in tags.lower().split(',')]
for t in set(tags):
tag = graph.merge_one("Tag", "name", t)
rel = Relationship(tag, "TAGGED", post)
graph.create(rel)
The user is found in the database with User.find(), which returns a py2neo.Node object. Then, another Node object post is created with the shown properties. A random id is generated with the uuid package’s uuid4() method, and the timestamp and date are set with functions I defined elsewhere in models.py:
def timestamp():
epoch = datetime.utcfromtimestamp(0)
now = datetime.now()
delta = now - epoch
return delta.total_seconds()
def date():
return datetime.now().strftime('%Y-%m-%d')
With both the user and post variables, we can create a (:User)-[:PUBLISHED]->(:Post) relationship in the graph by passing a py2neo.Relationship object to Graph.create(). Finally, the tags are split on commas and lowercased. For each of these tags, a relationship (:Tag)-[:TAGGED]->(:Post) is created. We use the Graph.merge_one() method to ensure we are finding or creating a Tag node with the given name property.
The form where a user adds a new post is located in index.html:
{% extends "layout.html" %}
{% block body %}
<h2>Home</h2>
{% if session.username %}
<h3>Share New Post</h3>
<form action="{{ url_for('add_post') }}" method="post">
<dl>
<dt>Title:</dt>
<dd><input type="text" size="30" name="title"></dd>
<dt>Tags (separated by commas):</dt>
<dd><input type="text" size="30" name="tags"></dd>
<dt>Text:</dt>
<dd><textarea name="text" rows="5" cols="40"></textarea></dd>
</dl>
<input type="submit" value="Share">
</form>
{% endif %}
<br>
<h3>Today's Recent Posts</h3>
{% include "display_posts.html" %}
{% endblock %}