1st place, hackathon 2023

AgroBasket

A marketplace where farmers list produce and customers buy it from them directly, without a middleman.

When
March 2023
Apps
Customer storefront and farmer portal
Type
Django web app
Stack
Python, Django, SQLite, JavaScript, Bootstrap
Problem
Produce passes through several traders before anyone buys it, and each one takes a cut from the farmer.
Solution
One site with two sides: farmers list what they grow, customers browse it and fill a cart.
Result
Won 1st place at the hackathon. Accounts, profiles, a product catalogue and a working cart. Farmer uploads and checkout were the next things to build.

The idea

By the time fruit and vegetables reach a shop they have usually passed through a wholesaler and one or more traders, and each of them takes a margin out of what the farmer gets paid. AgroBasket puts both ends of that chain on one site, so a farmer can sell straight to the person eating the food.

Two ways in

It's a single Django project split into two apps. Customers use the site root and farmers use /farmer. Each side has its own pages, but both sign in through Django's built-in auth, so there is one user table and one session system to look after.

Customers

  • Sign up and log in
  • Profile with a delivery address
  • Product catalogue
  • Cart
  • Order tracking page

Farmers

  • Sign up and log in
  • Profile
  • Product upload form
  • Dashboard

How the cart works

Four models hold the cart together:

What the cart is made of
  1. UserDjango auth, shared by farmers and customers
    has
  2. Cartcustomer, cart_id (UUID), completed
    has
  3. Cartitemscart, product, quantity
    points to
  4. Productsname, category, price, image, stock status
  1. Press Add to Cart

    Each product card carries its id. The click posts that id to /updatecart as JSON, with Django's CSRF token in the header.

  2. Find the open cart

    The server looks up the customer's cart that isn't completed yet, and creates one if there isn't. Each customer has exactly one open cart.

  3. Find the line

    It does the same for the line item: one row per product in that cart. Adding a product that's already there raises its quantity by one instead of adding a second row.

  4. Show the new total

    The page reloads, and the cart's totals are worked out from its line items when the page renders.

Working out the total

The cart doesn't store a total. It adds one up from its line items each time it's asked, so the total can't drift out of step with the items. Changing a quantity box in the cart posts the new number to /updatequantity. A line whose total reaches zero deletes itself.

An example cart
ProductPriceQtyLine total
Banana20× 360
BlackBerry35× 270
Cart5 items130

Products and prices are the ones seeded in the project's database; the quantities are an example.

Where it stopped

Working
Customer and farmer accounts, customer profiles, the product catalogue, and adding, changing and totalling cart items.
Front end only
The farmer upload form and dashboard are built as pages but don't save anything yet. Products are added through the Django admin for now.
Not started
Checkout and payment. The tracking page shows no orders, because a cart can't be completed yet.