DIENSTAG - Thoughts on my first website clone coding project

김하성·2021년 3월 1일
1
post-thumbnail

Dienstag on Youtube!
Github repo

After a month-long crash course on python, django, HTTP requests/responses, and relational databases (mysql) at WeCode, I completed a 2-week clone coding project on Freitag (freitag.ch), a Swiss-based company that converts recycled truck tarps and seatbelts into stylish bags and accessories. Since Freitag uses recycled materials to manufacture their products, each of their products are unique and one-of-a-kind. This presented a few interesting challenges and curve-balls that made this clone-coding project a joy to work on! I learned a bunch of things along the way--especially about working as a team, refactoring code, and making the most out of django's powerful ORM tools. Big thanks to my team members who were truly a pleasure to work with!!

🙌 Frontend:

강민지
변미현

🙌 Backend:

안재이
허정윤
김하성 (me!)

🛠 Tools Used:

Frontend:

  • html
  • css
  • javascript
  • react
  • context API
  • git/github

Backend:

  • python
  • django
  • AQueryTool
  • MySQL
  • git/github

Project Workflow (SCRUM)

  • weekly SPRINT meetings
  • daily standup meetings
  • Trello for keeping track of work being done (backlog, this week, doing, and done)
  • Slack for open communication with team

Data Modelling (models.py)


We used AQueryTool to model the basic data structure of Freitag's website. One of the hardest parts of modelling Freitag's website was the cart feature. Initially, we considered both products and vouchers, which are basically Freitag gift cards that customers can purchase. While each product is unique and thus has a quantity of 1 (customers cannot add more than 1 of a product), vouchers are not unique and can thus be added in large quantities. To accommodate for both products and vouchers, we ended up creating a Cart table that sort of served as a many_to_many middle table between orders, products, and vouchers. Setting product_id and voucher_id as null in the middle Cart table allowed users to have an order that contained many carts, each of which contained either a product or a voucher(s). Although we ended up removing the voucher feature from our clone webdsite due to time constraints, modelling the cart feature while considering both products and vouchers was a great learning experience!

"Dienstag" Main Features

User (signup and login)

  • Used bcrypt python library to hash passwords and store encoded passwords in database
  • Used pyjwt to create tokens to authorize user access to certain features of the website
  • Used a login decorator for user authorization (pyjwt)

Product

  • Created overall view of products based on bag type (i.e. backpacks, tote bags, messenger bags)
  • Created detailed view of each product (based on which product the user clicks on)
  • Created a filter component according to bag color and size (using query strings)

Cart

  • Users can add items to cart
  • Users can remove items from cart
  • Users who have created accounts can save their cart information and access it later by logging back in
  • Nonusers (users who haven't created accounts) can add items to cart and purchase items, but their cart information is removed if they exit the browser (frontend manages nonuser cart information using local storage). Although we ended up removing the nonuser component from our clone website due to time constraints, it was fun considering the different ways of storing user/nonuser cart information either in the database or in local/session storage.

What I Contributed:

  • cart/views.py
  • cart/urls.py

I drafted the views.py and urls.py for the cart feature of our clone website. I drafted a CartView that included three methods (get, post, delete). Initially, I drafted separate classes for users and nonusers (UserCartView and NonUserCartView), since we initially planned on including the cart feature for both users and nonusers. I also wrote code for adding vouchers to user carts, which I later removed since we ended up not including the voucher feature. Writing code for adding both products and vouchers to a user cart and viewing user carts (POST and GET methods) was definitely the hardest part for me. For accessing user cart information (Read in CRUD), I first attempted to divide products and vouchers using two if statements:

After receiving code review from a WeCode mentor, I realized that this code could be simplified by using a simple list comprehension and one-line if-else statements:

I definitely learned a lot by refactoring my code to make it simpler and easier to follow. Even though the code I initally wrote worked fine, I realized that writing your code in a simple and logical manner is important for readability and speed. Receiving code review also humbled me a lot as an aspiring programmer. I realized that I still have a long way to go before I can consistently write concise and effective code.


The highlight of this project was definitely working with our frontend team members to connect our code and see if our code worked!

Bump in the Road


In the middle of the second week of our project, Freitag closed their website to re-design different aspects of their website. Had this happened a few days earlier before our frontend team members finalized their design layouts (html/css), we would have been in deep trouble 🥶

Key Takeaways (insights gleaned from working on Dienstag):

  • Modelling is by far the most important part of backend web API development. With django's powerful ORM tools, if you model well, views.py writes itself.
  • When modelling data, instead of analyzing different components of the website visually (according to the website's layout and design), analyze the components from a data perspective. It's easy to misrepresent or overthink data by looking at the features of a website from a design/layout perspective. I found this particularly hard to do since analyzing a website according to its layout/design is a knee-jerk reaction for most people (especially those unfamiliar with data modelling)
  • Take advantage of django's powerful ORM tools, especially its lookup feature to follow relationships across different data tables (SQL JOIN clause). Using two underscores, you can filter through data by accessing different attributes of tables that are related:
if Order.objects.filter(user_id=user_id, order_status__name=ORDER_STATUS_CHECK, carts__product_id=product_id).exists():

Moving Forward:

There are definitely a bunch of features that I would love to continue working on with our Dienstag team members (user vs nonuser, voucher, map feature, newsletter feature, chatbot feature, and more!). I definitely learned a lot from the two weeks working on recreating Freitag from scratch, and I feel much more prepared for my second clone-coding project at WeCode.

profile
#mambamentality 🐍

4개의 댓글

comment-user-thumbnail
2021년 3월 2일

YO MARK(님)~~ 정말 고생 많으셨습니다!!! 팀 케미도 넘 좋아보이고 사이트도 넘 멋있어요🙏🔥 무한 respect... you guys did an amazing job!!!! Two thumbs up~~~ 👍 👍

답글 달기
comment-user-thumbnail
2021년 3월 2일

good MARK(님)!

답글 달기
comment-user-thumbnail
2021년 3월 2일

하성 님~ 차마 다 이해하지는 못 했지만(😂) 고생 많으셨습니다~ 2차도 화이팅 화이팅~~

답글 달기
comment-user-thumbnail
2021년 3월 9일

Good job, Mark!

답글 달기