A Discussion page, where users can sign up. Create a user profile, upload a profile image and write a short biography. Inspired by the website Reddit, developed with a simpler approach with the possibility of scaling. As well as uploading and reading other posts, users can engage with other users in the form of comments and likes throughout the different posts. Features that will be implemented shortly is the ability to see others users' pages. As well as a more categorized sorting system of the posts created.
A breif overview of all the sections I have implemented in the page.
-
Navigation Bar
- The navbar is featured on all pages, with a sleek design that blends in with the overall layout of the page. An easy search function in the middle, as well as a navigation off-canvas nav menu that slides of from the right.
- The user will have the ability to log in to the page or signup if they have not already done so, If the user is logged in they can access their profile or add posts.
-
The landing page
- The landing page offers a simple welcome message along with a very short description of what the page offers. Its dynamic to the user.
- Lets the user know if they are logged in or not. Link to the latest posts.
-
Home page - Latest posts
-
Post Detail
-
The Footer
-
User Profile
-
The Sign Up Page
- To let users see other users profile pages plus send messages to eachother privately.
- Implement most liked posts on the home page, to let the users see the latest posts as well as the most liked.
-
I have chosen to go with the already imported django testcase that runs along with unitest, A testing package that lets me simulate the different functions and request that is required to make the site run smoothly.
-
URL testing
- I have written a test for each url of the page to see that the urls are resolved and working as should.
Results:
-
View testing
For each of the views of the application, I have written tests to conclude that they are working as they should. By simulating the requests that make the application run, such as POST, GET, DELETE.- By simulating the creation of a user to act as the authenticated user on the page, where then the user is tried in each of the different views. After the user is created I created a post for the user to see in the test GET request of the home page and post detail. In the test Add post view I create a post and simulate the POST method with a successfull status code of 200. The test DELETE request, gets the post that I have created in the beginning and performing the delete method on it. I know this by counting the number of posts before the action is called, then making the assertEquals to 1, to verify that 1 / 2 posts have been deleted. The same has been done for deleting comments on a post, liking a post and editing a post. With the same structure as above. All to simulate a response code of 200.
Results:
-
Model testing
The testing of models has been done just to see that the post_save works on both slugify post title, as well as user is bloguser on signup.- For the slugify title, the test is simply done be checking if the title of the post is equal to the slug of the post in small letters with each word seperated with a dash.
- For the user, I have created a post save method that saves the user as a bloguser on signup. How I check that this works is by double checking the value User: "username" is equals to Bloguser: "username" when running the test. By knowing that they are the same I know the post save method has been complete.
Results:
-
- A link to an external document where I have documented the manual testing procedures.
- I go through each of the functions of the website in a detailed manner. To ensure that the current features functions as they should. Manual-Testing Document
- No errors were returned when passing through the official W3C validator
- No errors were found when passing through the official (Jigsaw) validator
- All the python code has been copied and pasted into a pep8 checker online.
- There are no pep8 issues in the problems tab of the bash-terminal that needs to be addressed.
- 4 lines of code in settings.py that are to long, but will brake the code if split up.
The web-application has been deployed using Heroku & AWS buckets, in this section I will explain the steps I took to deploy the website.
-
Heroku:
- Go the Heroku page and create an account if you dont already have one.
- When logged in proceed to create new app, and select the region closest to you.
- Name the application with a unique name.
- After the app as been created, Go to resources tab and search for Heroku postgres, add the free version.
- Make sure you have pushed the completed version of your code to github, then select deploy with github on the deploy tab of heroku.
- Search for the repository, select the correct one.
- Make sure all the requirements are installed from this requirements.txt file.
- In your root directory of your codebase, create a new Procfile and add. web: gunicorn projectname.wsgi
- In the environment variables add a new variable called DISABLE_COLLECTSTATIC : 1
- In heroku, go to the deploy tab and press deploy branch.
- The application should now be deployed without staticfiles.
-
AWS buckets:
-
Go to AWS page and create an account. A credit card is needed.
-
In the search bar, search for S3.
-
In S3, create a new bucket. Prefferably named after the project.
-
Click on the bucket properties tab and enable static website hosting.
- Enter the default values of index.html and error.html.
-
On the permissions tab, scroll down to Block public access (bucket settings) and press edit. Turn off this setting and approve.
-
Further down on the page at CORS, paste these settings.
- [ { "AllowedHeaders": [ "Authorization" ], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ]
-
Now head up the page to bucket policy, and press policy generator.
- Policy type will be S3bucketpolicy
- Principal: *
- Actions: getObject
- Copy bucket ARN into the ARN field.
- Press Add statement and copy the policy from the policy generator into the bucket policy, and add /* to the ARN.
- Lastly on the access control list, grant everyone the list objects property.
-
In the top search bar search for IAM.
-
When in the page. Go to User Groups, and create a new one for the bucket to live in.
-
The tab section to the left, select policies. Then create policy.
-
In the JSON tab, select import managed policy. Select AmazonS3FullAccess.
-
Copy the ARN From the bucket created earlier and paste it into resources as ["ARN", "ARN/*"]
-
Click review policy, Name it and give a brief description.
-
Then press create policy.
-
Go back to groups. Select the group created for this purpose, and attach policy. attach the policy just created.
-
In the tab menu to the left select user, and create a user for the group created.
-
Select a suitable username, Add the user to the group created.
-
Download the csv file and save the file !IMPORTANT!.
-
-
Django
-
Install boto3 and django-storages
-
Add storages to installed apps in settings.py.
-
Paste in the following in the bottom of settings.py
if 'USE_AWS' in os.environ:AWS_STORAGE_BUCKET_NAME = 'milestone4-feed-bucket' AWS_S3_REGION_NAME = 'us-east-1' AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY') AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
STATICFILES_STORAGE = 'custom_storages.StaticStorage' STATICFILES_LOCATION = 'static' DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage' MEDIAFILES_LOCATION = 'media'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATICFILES_LOCATION}/' MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIAFILES_LOCATION}/'
-
-
Heroku
- In app page, go to settings and add the AWS keys to the environment variables.
- Along with USE_AWS for the above to work.
The live link can be found here - https://feed-news.herokuapp.com/
-
The wireframes have been created using the tool Figma. The design I've created is a simple but eye-catching design, with design principles that follow the 60-30-10 rule, where shades of grey, orange, and white have been utilized to capture the audience. The primary color, is used for the call-to-action buttons and links. A call for the user that here where the bright orange color is, a link / button to take you to another sections of the website. The secondary color is white, acting as a breaker between the orange and the grey. making the transition between the two colors smooth. The reason behind white is its naturall flow and nice contrast to both the primary and dominant colors. The Dominant color I've used is a shade of grey #333333. A nice slightly darker shade that brings out a nice feel to the overall website.
-
A link to the workflow management software used in the process of creating this application. Trello User stories have been created for each of the tasks that has
-
A flowchart created in lucid charts. Which displays how the models relates to eachother.
- AWS deployment code taken from:
- Testing code partially taken / learned from:
-
Tel aviv media and content taken from:
-
Sydney media and content taken from:
-
Portugal media and content taken from:
-
Bangkok media and content taken from: