HW3 - Seddit


Due Date: Tuesday 12/3 11:59PM

(Right click and “Save Link As…”)

seddit.zip

For this assignment, you’ll be creating a Reddit-like forum (hence the terrible name “Seddit”) using Django! Seddit will have the following pages:

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:

Create Post

The template for this page is included as create_post.html. You need to do the following:

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:

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):