HW3 - Seddit
Due Date: Tuesday 12/3 11:59PM
(Right click and “Save Link As…”)
For this assignment, you’ll be creating a Reddit-like forum (hence the terrible name “Seddit”) using Django! Seddit will have the following pages:
- User log in and sign up
- Homepage
- Create post
- Post view (including commenting, upvotes/downvotes, and deletion)
- Subseddits (basically sub forums if you’re not familiar with Reddit)
The provided code is a stubbed version with the core models implemented, along with a few templates. Your job is to complete the functionality above. Each task is detailed below. Error handling is not required, but if you wish to do so, each template with a form has a message
context variable that may be helpful. Additionally, anything you print will show in the terminal while you’re running the Django server, which may help for debugging.
All imports you should need have been included in views.py
. You may need more if you’re doing something for extra credit.
Overview
Similar to the Django exercise we did in class, you’ll find two folders. The seddit
folder is where settings and things will live, you shouldn’t need to touch anything in here unless you’re attempting to add additional functionality for extra credit. The blog
folder is where you’ll be working out of.
First, get familiar with the defined models in models.py
. We have Posts, Tags, Comments, and Votes. Posts can be tagged by their creators, commented on by anyone, and upvoted on by anyone. We use the built-in Django User as our user model because of the nice authentication functionality that it comes with out of the box (which you will see later). Note the inclusion of class Meta
on Tag and Vote. These basically just tell Django that there are uniqueness constraints. That is, a post can only have unique tags (no repeats) and a user can only vote once per post.
Start by making migrations and then applying them.
python manage.py makemigrations blogs
python manage.py migrate
Once you’ve done that, you can run the server to see what’s included. You should see a basic homepage with some TODOs along with login and sign up links. These links should be fully functional. When a user is logged in, you should see the username and a logout link. It may be useful to examine index.html
to see how exactly this is done.
Additionally, there are some included templates for you to use. Below is a table that describes each file and what context variables it has.
Template | Description |
---|---|
index.html |
Should be used for the homepage. Expects a context variable of posts to display. |
post_detail.html |
Should be used for the post detail page. Expects a context variable of post to display. Also displays comments and includes a form for submitting a comment. Optionally has a message variable in the context to display errors. |
create_post.html |
A simple form to create a post. |
login.html |
A login page. |
signup.html |
A user sign up page. |
Tasks
User Log In and Sign Up
This is already implemented for you, but there are some things that may be useful for later tasks. First, if a user is logged in, the request object that is passed as an argument to a view method will have a user
attribute that contains the user’s information. If the view is class, e.g. a generic Django view, the request object can be accessed from self
. For example
# I can access the user's information like so
def my_endpoint(request):
request.user.username
class MyView(generic.ListView):
def my_method(self):
self.request.user.username
Additionally, Django auto includes a context variable in templates called user
that you can use. To check if a user is logged in, simply do user.is_authenticated
, which you can see in the included index.html
.
Finally, sometimes we would like for pages to be authenticated, like create post. That is, in order to view the page, a user should be logged in. Django easily allows us to do this by decorating view methods. Any request from a non-authenticated user will simply 404.
from django.contrib.auth.decorators import login_required
@login_required
def my_endpoint(request):
...
Homepage
This view is already implemented for you, but there’s a bit to do in the template index.html
. Specifically:
- If there are no recent posts, display something along the lines of “No posts to show.”
- If there are posts, then fill in the table data marked TODO accordingly.
- Each post title should link to that post’s detail page.
- Add a link to the create post endpoint if the user is logged in.
Create Post
The template for this page is included as create_post.html
. You need to do the following:
- Add a view with the path
create_post/
and namecreate_post
for this page. This view should be authenticated. - The view should properly create a new
Post
in the database. - Once the post is created, it should redirect the user to the post detail page for the new post.
Post Detail
This task will likely be the most involved. The template for this page is included as post_detail.html
. Included is some content of the post, a delete button if the user owns the post, an upvote button, comments, and a comment form. You will need to do the following:
- Add a view with the path
post/<int:pk>
and namepost_detail
for this page. - Under the post title and user, add two pieces of information in the template
- The tags the post has (you may need to define a helper method on the
Post
class for this) - The number of upvotes the post has
- The tags the post has (you may need to define a helper method on the
Post Comments
The existing comment form on the post detail page posts to the endpoint comment/<int:post_id>
, which should be named comment
. This endpoint should be authenticated. It should create a Comment
in the database and then redirect the user back to the detail page for the post, meaning that the user should see their comment afterwards.
Upvoting Posts
There is an included button on the post detail page that posts to the endpoint post/<int:post_id>/upvote
, which should be named post_upvote
. This endpoint should be authenticated. It should create a Vote
in the database and then redirect the user back to the detail page for the post. If a vote already exists for that user and post, then you do not have to surface any errors, but the page should effectively do a refresh.
Deleting Posts
There is an included button to delete the post on the post detail page if the user who owns it is logged in. This posts to the endpoint post/<int:post_id>/delete
, which should be named post_delete
. This endpoint should delete the corresponding post if the user owns it. It should redirect to the homepage afterwards.
Subseddits
You will need to create this page from scratch! No template has been included. The purpose of this page is to be something similar to subreddits. The URL path should be in the form s/<subseddit>
and named subseddit
. The page for each subseddit should only include posts with a tag equal to the subseddit
. It may be helpful to finish the above first, then copy index.html
as a starting point.
Extra Credit
Extra credit for this assignment is open ended. Generally, any additional functionality will count! Some ideas (in roughly easiest to hardest):
- Making the webapp pretty, i.e. adding a nav bar, a theme, etc
- Searching post titles
- Error handling and displaying to the user
- A bio page for a user
- Blocking/unblocking users
- Deploying to the cloud