How to Create a Grocery Bag App Using Django (Part-I)
Introduction
Grocery Bag is a way to store grocery items for marketing. It will contain a homepage that will be showing all the list of items to buy and already bought. Users will be able to add items and update items, and can even delete them.
Requirements
- Users can register themselves and will have a login/logout system.
- Users can create a list of grocery items to buy.
- Create a flag like - bought, left and not-available
- Create a bar to show saved lists, and on the home page, it will show all the lists according to date.
Screenshots
Below given some screenshots that will give you an idea of what we're building.
Index Page
Add new item
Update an item
Project Setup
Before you start with the project setup, make sure you have Python installed in your system. You can verify it with the following command:
$ python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
If you get the above output, you have Python installed. If not, you can download it from this page.
We'll be using a virtual environment env
for our project. Let's create the environment:
$ python -m venv env
Note: You can use python3
in place of python
as per your requirement.
To activate the environment, use the command:
- On Windows, run:
$ env\Scripts\activate.bat
- On Unix or MacOs, run:
$ source env/Scripts/activate
Now that we have the virtual environment activated, we can install the required libraries using the command below:
$ pip install Django
The above command will install Django in our virtual environment. Now we are ready to create our Django project called GroceryBag
. Run the following command to create the project in the current directory:
$ django-admin startproject GroceryBag .
Now, as per the requirements, we need two apps - bag
to handle the CRUD operations on the Grocery bag, and accounts
to handle the authentication. Let's create these apps one by one.
$ python manage.py startapp bag
$ python manage.py startapp accounts
After the two apps have been created, create separate urls.py
file in both of the apps directory, and add the following content in both files.
from django.urls import path
urlpatterns = [
]
Then we need to register these two apps in our project. So, open the settings.py
in the GroceryBag directory and add the two apps to the INSTALLED_APPS
list.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps below
'accounts',
'bag',
]
At the later stage of the project, we'll be deploying it on a free cloud platform. So, we need to setup environment variables. Let's install python-decouple to help us with them:
$ pip install python-decouple
Once installed, create a file .env
in the current directory and add the following content inside it.
SECRET_KEY=django-insecure-6wx#%@2ift=4@1(\*eiw5n&rh!5t!bytp6=#8viz^$ola#p5nsm
DEBUG=True
Now, we need to make a few changes in the settings.py
file. Let's make them:
"""
Django settings for GroceryBag project.
Generated by 'django-admin startproject' using Django 3.2.9.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
from decouple import config
## Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path( __file__ ).resolve().parent.parent
## Quick-start development settings - unsuitable for production
## See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
## SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY') # Get value from environment variables
## SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG') # Get value from environment variables
ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] # Add these two for now
## Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps below
'accounts',
'bag',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'GroceryBag.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Add the templates directory
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'GroceryBag.wsgi.application'
## Database
## https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
## Password validation
## https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
## Internationalization
## https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
## Static files (CSS, JavaScript, Images)
## https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
## Default primary key field type
## https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
In the above file, we have made important changes related to templates and static directories.
After this, create a templates
directory and a static
directory in the current directory for HTML files and static files(CSS, JavaScript, Images) respectively. Inside the static folder, create another folder called css
where all the CSS files will be stored.
Download the HTML templates and CSS file from here and add them in their respective directories.
Now, open the GroceryBag/urls.py
file and modify it as below:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('bag.urls')),
path('accounts/', include('accounts.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
In the above script, we have included the URLs from the bag
and accounts
apps. Also, we have created URL pattern for the static files we are going to serve.
The next thing we need to do is to migrate the database using the following command:
$ python manage.py migrate
When you run the command, you'll see some output. After it has completed, you'll see a db.sqlite3
file in the current directory. This shows that our database has been migrated successfully.
Now, we can run the server as:
$ python manage.py runserver
When you run the server, you'll get a URL in the console. Open that in your favorite browser and you'll see a similar output.
Don't worry about this error for now. It just tells us that, it's not able to find the /
route. We'll resolve this in the next blog. With this, we have completed the setup of the project. You can match the directory structure until now:
.
├── GroceryBag
│ ├── **init**.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── accounts
│ ├── **init**.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── **init**.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── bag
│ ├── **init**.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── **init**.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── static
│ └── css
│ └── style.css
└── templates
├── add.html
├── index.html
└── update.html
Conclusion
In this blog, we have understood what we are going to build in this project. We have also setup our project. In the next blog, we'll start working on the project. Stay tuned!
Code till now: https://github.com/ashutoshkrris/Grocery-Bag/tree/blog1