Print statements is a safe haven that brings artists & consumers together in harmony. It allows artists to take control of the distribution of their work, and share their passions with the general public. As well as bringing an interactive, engaging platform for the public to find pieces from their favourite artists, as well as allowing them to discover new & upcoming figures within the art world.
The live link for "print(STATEMENTS)" can be found HERE
The intent of the site is to bring Artists & Consumers together. “print(STATEMENTS)” Is an online printing service where known & aspiring artists can submit their work. In doing so, they will also select the medium in which they would like their work to be printed, along with the price, and number of limited edition copies they would like to sell. Upon doing so, the artwork will then be displayed on the site, available to the general public for purchase. Each unique piece of artwork will be signed & numbered, and issued with a statement of authenticity, so that enthusiastic collectors can own a piece of their favourite artist.
To build a platform that allows artists to easily share their work and passions with their fans, and art lovers who have yet to discover their talents. As well as to bring an engaging experience to artists and consumers alike. By having a display of artwork from a range of individuals, art-lovers will be able to easily peruse through pieces that engage them in a way that only art can.
For everyone with a thirst for beauty in their lives. For the experienced art collectors who know what they are looking for, as well as those just discovering the art world with fresh new eyes. The ideal user age is between 20-50 years of age.
With a clean, easy to follow layout, the user - both artist and consumer alike - are guided through the features of the website with an ease of navigation.
For Artists to easily be able to supply their work to the art world and be discovered by new & old collectors. For Collectors to not only find works by the artists they admire, but to also discover new artists along the way.
To become instantly engaged with the design of the site, and feel intrigued to explore all it has to offer.
- To create a profile page for each artist, which the site users can peruse.
- To view all the available artwork created by an artist both on their profile page, and by clicking on the artist name when viewing an artwork.
- To allow users to follow artists directly, and receive email notifications when new works are available for sale.
- To have an online shop that will make the individual artworks available for sale.
- For the remaining number of artworks to be instantly displayed on the prints page under "remaining prints."
- To provide access for the artists to not only select the number of limited edition prints they would like to sell, but also choose the size of the work, along with the medium on which is is printed (canvas, glossy print, mat, etc...)
Not all stories have been implemented. Some have been left for future implementations as the site grows and expands.
- I can submit new blog posts so that I can inform site visitors & artists of new events, artists, and more.
- Story points: 3
- I can moderate blog comments so that the feedback provided is appropriate.
- Story points: 1
- I can create a log in / sign up page so that artists and visitors can sign up to the site.
- Story points: 2
- I can create a user profile so that I can be found & viewed on the site.
- Story points: 3
- I can upload artwork so that I can share it with art enthusiasts.
- Story points: 5
- I can select a medium, and print size so that I can have the work printed.
- Story points: 1
- I can choose how many prints I would like so that my work is sold as a limited edition run.
- Story points: 1
- I can set a price so that I can sell my work.
- Story points: 1
- I can visit the blog so that I can see what is new.
- Story points: 5
- I can comment on blog posts so that I can give my feedback.
- Story points: 2
- I can like blog posts so that I can easily share my enthusiasm.
- Story points: 1
- I can peruse the gallery so that I can discover new artists, and new artworks by artists I already know.
- Story points: 5
- I can follow artists so that I can be updated when new work is released.
- Story points: 3
- I can like an artists so that I can show my appreciation.
- Story points: 2
All fonts were obtained from the Google Fonts library. I chose the following fonts for the page:
- Kanit: Site heading/logo, Blog & print titles
- Permanent Marker: site navigation & site buttons
- Shadows Into Light Two: all remaining site text
- All photography for the fictional "artists" was supplied by me.
- Two drawings have also been uploaded, with the consent of the artist. They have been named in the Credits section.
- The button to invite you to submit a new artwork will be found on the "Prints" page.
- It is only visible to users who are signed in.
- Online shop
- Artist profiles
- Contact page
- Password reset
- Social media sign-in
TEST | ACTION | EXPECTATION | RESULT |
---|---|---|---|
printstatements - settings.py | PEP8 validator | No issues found | ✅ |
printstatements - urls.py | PEP8 validator | No issues found | ✅ |
blog app - forms.py | PEP8 validator | No issues found | ✅ |
blog app - models.py | PEP8 validator | No issues found | ✅ |
blog app - views.py | PEP8 validator | No issues found | ✅ |
blog app - urls.py | PEP8 validator | No issues found | ✅ |
blog app - admin.py | PEP8 validator | No issues found | ✅ |
artprint app - forms.py | PEP8 validator | No issues found | ✅ |
artprint app - models.py | PEP8 validator | No issues found | ✅ |
artprint app - views.py | PEP8 validator | No issues found | ✅ |
artprint app - urls.py | PEP8 validator | No issues found | ✅ |
artprint app - admin.py | PEP8 validator | No issues found | ✅ |
style.css | W3C - Jigsaw validator | No issues found | ✅ |
Home page - html | W3C validator - source code | No issues found | ✅ |
About page - html | W3C validator - source code | No issues found | ✅ |
Blog page - html | W3C validator - source code | No issues found | ✅ |
Prints page - html | W3C validator - source code | No issues found | ✅ |
Sign-in page - html | W3C validator - source code | No issues found | ✅ |
Home page - html | lighthouse | Acceptable scores | ✅ |
About page - html | lighthouse | Acceptable scores | ✅ |
Blog page - html | lighthouse | Acceptable scores | ✅ |
Prints page - html | lighthouse | Acceptable scores | ✅ |
Sign-in page - html | lighthouse | Acceptable scores | ✅ |
Brave browser | Launch site | Site opens without issue | ✅ |
Chrome browser | Launch site | Site opens without issue | ✅ |
Safari browser | Launch site | Site opens without issue | ✅ |
TEST | ACTION | EXPECTATION | RESULT |
---|---|---|---|
Home page - responsiveness | Size site down to 320px | all elements stay on screen | ✅ |
Home page - responsiveness | Size site up to 1920ox | all elements stay on screen | ✅ |
About page - responsiveness | Size site down to 320px | all elements stay on screen | ✅ |
About page - responsiveness | Size site up to 1920ox | all elements stay on screen | ✅ |
Prints page - responsiveness | Size site down to 320px | all elements stay on screen | ✅ |
Prints page - responsiveness | Size site up to 1920ox | all elements stay on screen | ✅ |
Blog page - responsiveness | Size site down to 320px | all elements stay on screen | ✅ |
Blog page - responsiveness | Size site up to 1920ox | all elements stay on screen | ✅ |
Sign-in page - responsiveness | Size site down to 320px | all elements stay on screen | ✅ |
Sign-in page - responsiveness | Size site up to 1920ox | all elements stay on screen | ✅ |
TEST | ACTION | EXPECTATION | RESULT |
---|---|---|---|
Blog - Create | Add new instance to DB | Instance created | ✅ |
Blog - Read | Retrieve all instances | Instances visible in UI | ✅ |
Blog - Update | Modify an instance | Mods saved & visible | ✅ |
Blog - Delete | Delete an instance | Instance removed from UI | ✅ |
Comments - Create | Add new instance to DB | Instance created | ✅ |
Comments - Read | Retrieve all instances | Instances visible in UI | ✅ |
Artprint - Create | Add new instance to DB | Instance created | ✅ |
Artprint - Read | Retrieve all instances | Instances visible in UI | ✅ |
Artprint - Update | Modify an instance | Mods saved & visible | ✅ |
Artprint - Delete | Delete an instance | Instance removed from UI | ✅ |
Like - Create | Add new instance to DB | Instance created | ✅ |
Like - Delete | Delete an instance | Instance removed from UI | ✅ |
TEST | ACTION | EXPECTATION | RESULT |
---|---|---|---|
Navigation bar | Click on nav link | user routed to correct page | ✅ |
Footer links | Click on footer links | user routed to new browser tab | ✅ |
Like button | Click "like" | Post liked/unliked accordingly | ✅ |
Edit button | Click edit button | user navigated to edit screen | ✅ |
Delete button | Click delete button | print/blog removed from UI | ✅ |
Internal links | Click link | User routed to appropriate page | ✅ |
Login | User logs in | UI updates & user is logged in | ✅ |
Sign up | User signs up | new account created for the user | ✅ |
Logout | User clicks logout | UI updates, user is logged out, user cannot create a post | ✅ |
- index.html page not loading:
- Through trial and error, I changed the view code from a class to a function.
- as well as removed the
.as_view()
from the URL path.
- CSS styles not loading on blog page:
- This Django tutorial indicated that the styles were incorrectly linked.
- This was resolved updating the href link in the base.html to
{% static 'css/style.css' %}
- Error message after installing Allauth:
- Tutor support informed me that Heroku had updated my database url value.
- This was resolved by updating the env.py file with the new URL.
- Invalid "syntax" error after installing crispy-forms:
- A comma was missing from within the BlogPostPage class.
- Django error message after adding comment form:
- CSRF token had been added as CRSF.
- Correcting the error resolved the issue.
- Console error after adding "Categories" field to Artprints model:
- The console indicated that a default field had not been supplied.
- As I did not remember that it would need to be an integer, I added
default='undecided'
to the field. - This produced further error messages.
- I corrected the model, and attempted to migrate the changes once more. The same error continued to display on the console.
- I looked up how to revert the migrations on Stackoverflow using the following command:
./manage.py migrate artprints zero
, but this did not resolve the issue. - After consulting with a fellow student who had experienced something similar, Mats Simonsson, I then deleted the files out of the migrations folder within my app folder.
- This resolved this issue.
- However upon contemplation, I have understood that had the database been significantly populated with data, this would not be a reasonable approach to take, as it would eliminate important information.
- URL paths for second app:
- Being unable to submit an empty string as the first parameter in the main URLs folder, my weblink was displaying as prints/prints/.
- Having tried multiple suggestions from numerous sources, I instead resorted to changing the main URL path to art so that any new URL path created in the second app file, would then display as art/pathname
- This is not the resolution that I was looking for, however for aesthetics, I have accepted it as the solution for now.
- Hero & About image not loading on deployed site:
- These two images were stored directly within the django app as opposed to being uploaded to Cloudinary.
- I tried numerous articles that suggested to change the URL path linked in the CSS file, and tried the following:
background: url(/static/images/gallery-wall.jpg) no-repeat;
: As shown in Simpleitbackground: url('{% static "/images/gallery-wall.jpg" %}') no-repeat;
: As showing in Stackoverflowbackground: url('{% static "images/gallery-wall.jpg" %}') no-repeat;
background: url("{{ STATIC_URL }}images/gallery-wall.jpg") no-repeat;
background: url(static("images/gallery-wall.jpg"));
- As none of these resolved the issue, and I was unable to ascertain the solution that I required, I instead resorted to loading the images directly into the HTML files as opposed to the CSS.
- Issue resolved.
- Art submission form unable to complete:
- Terminal error suggested no file was selected.
- I read numerous articles on stackoverflow, cloudinary, comments on slack, and was unable to resolve this.
- Ger from Tutor support indicated that the required field was missing from my form tags
enctype="multipart/form-data
- Adding this resolved the issue.
- User unable to submit multiple prints:
- This was due to the slug field not being included in the form submission.
- Another side effect of this, is that when the print was then approved via the admin panel, should the admin not pay attention and approve it without inserting a slug, the entire prints page would then fail to load.
- To resolve this, the slug field was added to the form field.
- Have not yet figured out how to have this auto-populate as it would were it submitted directly from the admin panel.
- However, adding the slug field ensures that the "Create" feature of CRUD now works as intended.
- Blog post page pushes social links to left:
- Upon inspection in dev tools, the row containing the comments was being duplicated, causing the layout to shift.
- Issue resolved by moving the
{% endif %}
inside of the closing div for the row. - This then caused an issue with the view when the user was logged out.
- Once more, the opening & closing if statements needed to be moved outside the row entirely.
- Submit multiple comments:
- Due to how the comments section was set up in the html file, upon submission of a comment, regardless of approval, the form would no longer be available to the user. Instead, a display message was constantly shown, suggesting that the comment was still pending approval, even if it had been approved.
- To resolve this, the section in the HTML was removed, and instead a line was added to the view function so that a success message would display on the screen after submission. This then allows the user to go and submit multiple comments on the same post, regardless of whether they have an approved or pending comment already submitted.
- Testing CRUD functionality:
- Each of the features were tested multiple times to ensure that numerous new posts could be submitted, and that each post had the ability to be updated and edited by the user that submitted it.
- If a post is submitted by another user, the edit/delete buttons do not appear on the page.
- Forms test failed to run:
- When running the newly created test in forms.py, the following error occurred in the terminal: "Got an error creating the test database: permission denied to create database".
- A Slack comment provided the answer for this, & suggested that the new DATABASES variable in the settings.py file needed to be commented out, and the original one to be made active again for the tests to work.
- Following these steps allowed the test to perform as expected.
- AssertionError: 301 != 200:
- The second test implemented from the "Hello Django" project failed each time it was ran.
- The answer on how to resolve it was ascertained from Stackoverflow, and adding an
follow=True
to the code in turn caused the tests to pass.
- None that I'm aware of
- HTML5
- CSS3
- Javascript
- Python
- Django
- SQL - Postgres
- Google Fonts - for the font families:
- Font Awesome - to add icons to the social links in the footer element.
- GitPod - to create my html files & styling sheet before pushing the project to Github.
- GitHub - to store my repository for submission.
- Balsamiq - were used to create mockups of the project prior to starting.
- Am I Responsive? - to ensure the project looked good across all devices.
- Favicon - to provide the code & image for the icon in the tab bar.
- Adobe Photoshop - for photo editing
- Django
- Bootstrap
- DrawSQL
- 'django<4' gunicorn
- dj_database_url psycopg2
- dj3-cloudinary-storage
- django-summernote (link)
- django-allauth (link)
- django-crispy-forms(link)
The site was deployed to Heroku. The steps to deploy are as follows:
- Install Django & Gunicorn:
pip3 install 'django<4' gunicorn
- Install Django database & psycopg:
pip3 install dj_database_url psycopg2
- Install Cloudinary:
pip3 install dj3-cloudinary-storage
- Creating the requirements.txt file with the following command:
pip3 freeze --local > requirements.txt
- a django project was created using:
django-admin startproject printstatements .
- the blog app was then created with:
python3 manage.py startapp blog
- which was then added to the settings.py file within our project directory.
- the changes were then migrated using:
python3 manage.py migrate
- navigated to Heroku & created a new app called print-statements.
- added the Heroku Postgres database to the Resources tab.
- navigated to the Settings Tab, to add the following key/value pairs to the configvars:
- key: SECRET_KEY | value: randomkey
- key: PORT | value: 8000
- key: CLOUDINARY_URL | value: API environment variable
- key: DATABASE_URL | value: value supplied by Heroku
- added the DATABASE_URL, SECRET_KEY & CLOUDINARY_URL to the env.py file
- added the DATABASE_URL, SECRET_KEY & CLOUDINARY_URL to the settings.py file
- add an import os statement for the env.py file.
- added Heroku to the ALLOWED_HOSTS in settings.py
- created the Procfile
- pushed the project to Github
- connected my github account to Heroku through the Deploy tab
- connected my github project repository, and then clicked on the "Deploy" button
- Due to Heroku revoking their frie tier access, the project has been redeployed using (Render)[https://render.com/] & (ElephantSQL)[https://www.elephantsql.com/] using the following instructions
- The live link for "print(STATEMENTS)" can be found HERE
- Mats Simonsson: A fellow student & friend who consistently helps me to troubleshoot when needed, support me constantly, and be my rubber duck.
- Martina Terlevic: A constant support system, providing reassurance, and the ability to calm me down.
- “I think therefore I blog” walkthrough: Provided the initial steps for setting up & deploying the site, as well as this, I also used the instructions they provided in order to implement a django blog into my app, following the walkthrough once again step-by-step. This also includes some formatting for the way each blog post is displayed on the blog page. Credits have been added as comments where code was used.
- "I think therefore I blog" + "Hello Django" + Slack + Stackoverflow + a fellow student: aided in the creation of the CRUD functions.
- Sean from Tutor Support: Singling out the most recent blog post with an "IF statement".
- Ger from Tutor support: assistance deciphering an error I could not understand. Re-linking the Heroku database in the env.py file with the new value resolved this.
- Ger from Tutor support: limiting view sections to a single user.
- 'Simple is Better Than Complex': creating types of user groups.
- Bootstrap: dropdown nav menu.
- Stackoverflow: connect URL paths from multiple apps.
- Stackoverflow: add form label.
- Stackoverflow: iterating over form field.
- Stackoverflow: Allauth email sign up required.
- Slack thread: Assistance with function to submit new prints.
- Ordinary Coders: implementing bootstrap messages in django.
- "Hello Django": The two tests implemented in this project were reused from the walkthrough project.
- All photography displayed in the Artists gallery was created by me.
- The drawings were provided by my friend, Eleni Sarri, with her permission.
- Hero image, Photo by: Tom Balabaud
- About page, Photo by: ¶Project Atlas
- Default blog post image, by: cottonbro