Building EC Apps with Django | Introducing Django (Part 1)

 2021-07-08

Building EC Apps with Django | Introducing Django (Part 1)

Python is known as a very popular programming language in the technology world. Born in the late 1980s, it is named after Monty Python, who is considered the father of the language. Web programming using Python quickly became popular. The tendency to learn Django – Web Framework, an application specialized in web design for the Python programming language, is becoming more and more common.

Hachinet will introduce you to the Django framework.

 

1. Overview


Django is a high-level web programming framework written in the Python programming language.

Django is fast and simple, so you can start web programming right away. In addition, Django has very good documentation, and the Django community is big and powerful.

Other frameworks don't take this seriously, but it follows the principles of DRY (don't repeat yourself). Django also supports ORM (Object Realistic Mapping).

MTV pattern:

  • Django follows the MTV (Model-Template-View) model, not the MVC (Model-View-Controller) model.
  • This model is used when creating an application that interacts with the user.
  • This model contains HTML code using the Django template language (DTL).
  • View (corresponding to MVC controller) is code written to control the interaction between the model and the template. That is, the client sends a request to the server and the server returns the result to the client.

To code Django, you need to have Python installed.

 

2. Project initialization


The first thing to do is to install a virtual environment for developing your project. Many Python libraries can do this, from virtualenv to pipenv. For convenience, Hachinet always uses pipenv to deploy the installation. Run the command pip3installpipenv

Next, create a folder containing the project and run the virtual environment.

$ mkdir GreatKart && cd GreatKart#プロジェクトコードを含むフォルダー

$ pipenv install Django#Django == 3.2

$ pipenvシェル

At this point, the command line format is (GreatKart) ... $. In other words, you are in the Great Kart virtual environment.

Create a code project using the command djan go-adminstartproject greatkart. This command will generate all the code needed for your first Django project. To add. Finally, it's a little unusual.

(GreatKart)...$ python3 manage.py migrate

(GreatKart)...$ python3 manage.py runserver

Project directory structure:

---GreatKart

|---greatkart (folder)

|---manage.py

|---db.sqlite3

|---Pipfile

|---Pipfile.lock

|---requirements.txt

|---.gitignore

3. Connect to MySQL


All web development frameworks require a database to manage user data. At a glance at the GreatKart / greatkart / settings.py file and scroll down to the Database section.

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }

Django uses the sqlite3 database management system by default, so when you run the above migrate command, the code folder will automatically create the file GreatKart /db.sqlite3. Django supports many popular database management systems in both SQL and NoSQL, so I always use MySQL as the database management system instead of sqlite3.

To use MySQL, you can install MySQL. Just perform the FLUSH PRIVILEGES step. In addition, you can install MySQL Workbench to facilitate MySQL management through the interface. You also need to install the mysqlclient library so that Python can connect to MySQl using the command pip3 install mysqlclient.

Edit the DATABASES code in the ettings.py file a bit.

DATABASES = { 'default': {

'ENGINE': "django.db.backends.mysql",

'HOST': "localhost",

'NAME': "GreatKart",

'USER': "root",

'PASSWORD': "12345678", }

If the command line is not giving an error, we are connecting successfully, you run the command python3 manage.py migration again and now you delete the db.sqlite3 file I can.

With the database name and password revealed too much like this, we need to create an ENV variable to not reveal personal things like this or anything else. The Python library you install is followed by Django-environ, which creates an .env file at the same level as manage.py with the following:

SECRET_KEY= ... # SECRET_KEY trong file settings.py

DATABASE_ENGINE=django.db.backends.mysql

DATABASE_NAME=GreatKart

DATABASE_USER=root

DATABASE_PASSWORD=12345678

DATABASE_HOST=localhost

DATABASE_PORT=3306

TIME_ZONE=Asia/

LANGUAGE_CODE=vi

In the settings.py file, you need to add it.

# To go up

import environ

env = environ.Env(

DEBUG=(bool, False)

environ.Env.read_env()

 

Then you need to replace the corresponding one from the following env file.

SECRET_KEY = env("SECRET_KEY")

DATABASES = {

"default": {

"ENGINE": env("DATABASE_ENGINE"),

"NAME": env("DATABASE_NAME"),

"USER": env("DATABASE_USER"),

"PASSWORD": env("DATABASE_PASSWORD"),

"HOST": env("DATABASE_HOST"),

"PORT": env("DATABASE_PORT"),

LANGUAGE_CODE = env("LANGUAGE_CODE")

TIME_ZONE = env("TIME_ZONE")

Run the migration and run server commands again as described above. If there are no errors, there is no problem.

 

4. Docker for the project


In Part 1, use the exit command to exit the virtual environment and create two files, Dockerfile, and docker-compose.yml.

$ touch Dockerfile

$ touch docker-compose.yml

The contents of the Dockerfile file are as follows:

# Pull base image

FROM python:3.7

# Set environmental variables

ENV PYTHONDONTWRITEBYTECODE 1

ENV PYTHONUNBUFFERED 1

# Set work directory

WORKDIR /code

# Install dependencies

COPY Pipfile Pipfile.lock requirements.txt / code /

RUN pip3 install pipenv && pipenv install --system && pip3 install -r requirements.txt

#Copy project

COPY .env /code/

COPY . /code/

The contents of the docker-compose.yml file are as follows:

version: '3'

services:

web:

build: .

command: python3 /code/manage.py runserver 0.0.0.0:8000

volumes:

- .:/code

ports:

- 8000:8000

depends_on:

- db

env_file:

- .env

db:

image: mysql:8.0.20

restart: always

command: --default-authentication-plugin=mysql_native_password --mysqlx=0

environment:

MYSQL_DATABASE: GreatKart

MYSQL_USER: root

MYSQL_PASSWORD: 12345678

MYSQL_ROOT_PASSWORD: 12345678

volumes:

- ".dbdata:/var/lib/mysql"

ports:

- '3305:3306'

env_file:

.env

This docker-compose.yml file creates two containers, web (to run a web application) and db (to run the MySQL database part).

Note that the value of depends_on must be the database container (db) name. mysql: In a db container that contains an image named 8.0.20, that is, it must be the version of MySQl on the machine,-. Volume values ​​starting with db ... must also correspond to the container name. This is the port value that needs to be set. {x} / 3306 (x is not 3306 to avoid duplicate ports). The value of both containers must be env_file because we are using environment variables

In addition, in the .env file, you also need to change the value of DATABASE_HOST = localhost to DATABASE_HOST = db (db container name).

To run Docker, run the following command:

$ sudo docker build .

$ sudo docker-compose build

$ sudo docker-compose up

At this point, we're running the web using a docking window without having to enter a virtual environment (pipev shell) to be able to run like Part 1 anymore.

 

5. Static and media settings


Django's static directories are where static folders and files are stored. Includes: CSS folders, Javascript, fonts, and fixed image files for websites.

You also need to download the files needed for use with Bootstrap 4. If you don't want to use it statically, you can use the Django-bootstrap4 library. The code needed for the static folder is here. You can download it for immediate use.

Then go to the settings.py file and add the following code that makes Django aware of your static directories.

STATIC_URL = '/static/'

STATIC_ROOT = BASE_DIR / 'static'

STATICFILES_DIRS = [

'greatkart/static']

STATIC_URL and STATIC_ROOT are where Django saves static files during deployment via the collectstatic administration command. Use STATICFILES_DIRS to allow Django to inspect all static files and load them into the archive

The static folder downloaded above is in the greatkart subdirectory at the same level as the settings.py file. Then run the command python3 manager.py collectstatic and Django will create a directory at the same level as the greatkart directory with the same path as the STATIC_URL variable.

If you later change the static directory, you must edit the static directory at the same level as settings.py and then run the collectstatic command again to initialize the new static directory.

Media is a folder that stores media-type files such as images and videos. From there, the server can be accessed and added, edited, and deleted. Configure the media as follows:

MEDIA_URL = '/media/'

MEDIA_ROOT = BASE_DIR / 'media'

You don't have to do anything else this time. If you have an access command, Django will either look for the Media folder or create it if it doesn't exist.

 

6. Customize user models, categories, and product models


In Django, this framework created a default model for a user named user. This default often limits the requirements of the developer, from which you need to customize and inherit the function.

Create a new app named accounts using the command python3manager.py startappaccounts, add "accounts" to the INSTALLED_APPS array variable in the settings.py file, and add a new variable AUTH_USER_MODEL ='accounts.Account' to notify Django To do. No longer use the default user model, but use an account instead

Add the following classes to your accounts / model.py file.

class Account(AbstractBaseUser):

first_name = models.CharField(max_length=50)

last_name = models.CharField(max_length=50)

username = models.CharField(max_length=50, unique=True)

email = models.EmailField(max_length=100, unique=True)

phone_number = models.CharField(max_length=50)

# required

date_joined = models.DateTimeField(auto_now_add=True)

last_login = models.DateTimeField(auto_now_add=True)

is_admin = models.BooleanField(default=False)

is_staff = models.BooleanField(default=False)

is_active = models.BooleanField(default=False)

is_superadmin = models.BooleanField(default=False)

USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', 'first_name', 'last_name']

objects = MyAccountManager()

def __str__(self):

return self.email

def has_perm(self, perm, obj=None):

return self.is_admin

def has_module_perms(self, add_label):

return True

Hachinet commented next to everyone to understand the information and features of the fields needed for the new table account and has created an additional class, MyAccountManager, to manage user interaction.

class MyAccountManager(BaseUserManager):

def create_user(self, first_name, last_name, username, email, password=None):

if not email:

raise ValueError('Email address is required')

if not username:

raise ValueError('User name is required')

user = self.model(

email=self.normalize_email(email=email),

username=username,

first_name=first_name,

last_name=last_name,

user.set_password(password)

user.save(using=self._db)

return user

def create_superuser(self, first_name, last_name, email, username, password):

user = self.create_user(

email=self.normalize_email(email=email),

username=username,

password=password,

first_name=first_name,

last_name=last_name, )

user.is_admin = True

user.is_active = True

user.is_staff = True

user.is_superadmin = True

user.save(using=self._db)

return user

Run the command python3manager.py makemigrations, then run python3 manager.py migrate to create an Account table in mysql. Then run the command python3 manager.py createsuperuser to create a super administrator for your system. Now the fields you need to fill in are the same as the customized create_superuser function.

Create additional classes in the Accounts / admin.py file to allow super admins to manage this table.

class AccountAdmin(UserAdmin):

list_display = ('email', 'username', 'first_name', 'last_name', 'last_login', 'date_joined', 'is_active')

list_display_links = ('email', 'username', 'first_name', 'last_name')

readonly_fields = ('last_login', 'date_joined')

ordering = ('-date_joined',)

filter_horizontal = ()

list_filter = ()

fieldsets = ()

admin.site.register(Account, AccountAdmin)

Then use the startapp command as above to create an app category and add the Category class to your category / models.py file as follows:

from django.db import models

from django.urls import reverse

class Category(models.Model):

category_name = models.CharField(max_length=50, unique=True)

slug = models.SlugField(max_length=100, unique=True)

description = models.TextField(max_length=255, blank=True)

category_image = models.ImageField(upload_to='photos/categories/', blank=True)

class Meta:

verbose_name = 'category'

verbose_name_plural = 'categories'

def __str__(self):

return self.category_name

The slug field is for identifying the category. The category_image field allows access to the media/photos/category folder. Don't worry if you don't have this folder. Django creates it for you. In the Meta subclass, declare the variables verbose_name and verbose_name_plural. If not, the category will appear on the super admin page, which is not the correct spelling. Run the make migrations and migrate commands to create the table.

Add code in the category /admin.py file so that the superuser can manage the category table.

class CategoryAdmin(admin.ModelAdmin):

prepopulated_fields = {'slug': ('category_name',)} # Gợi ý trường slug theo category_name

list_display = ('category_name', 'slug')

admin.site.register(Category, CategoryAdmin)

Then use the star app store command to create an app store to manage the product table. In the store / models.py file, create a Product class as follows:

from django.urls import reverse

from category.models import Category

from django.db import models

class Product(models.Model):

product_name = models.CharField(max_length=200, unique=True)

slug = models.SlugField(max_length=200, unique=True)

description = models.TextField(max_length=500, blank=True)

price = models.IntegerField()

images = models.ImageField(upload_to='photos/products')

stock = models.IntegerField()

is_available = models.BooleanField(default=True)

category = models.ForeignKey(Category, on_delete=models.CASCADE)

created_date = models.DateTimeField(auto_now_add=True)

modified_date = models.DateTimeField(auto_now=True)

def __str__(self):

return self.product_name

Add a superuser-managed app store to the store / admin.py file as well.

class ProductAdmin(admin.ModelAdmin):

list_display = ('product_name', 'price', 'stock', 'category', 'created_date', 

'modified_date', 'is_available')

prepopulated_fields = {'slug': ('product_name',)}

admin.site.register(Product, ProductAdmin)

greatkart / urls.pyファイルで、urlpattern変数を次のようにカスタマイズします。

urlpatterns = [

path('admin/', admin.site.urls),

path('', views.home, name='home'),

path('store/', include('store.urls')),

path('carts/', include('carts.urls')),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

さらに、アプリストアでは、urlpattern変数を使用してファイルurls.pyも作成します。

urlpatterns = [

path('', views.store, name='store'),

path('<slug:category_slug>/', views.store, name='products_by_category'),

path('<slug:category_slug>/<slug:product_slug>/', views.product_detail

 name='product_detail'),]

In the above, we declare the URL in the file greatkart / urls.py and the urlpattern variable declares a cluster of paths to other apps.

Django will automatically find the path in this file. The urlpattern variable in the store / urls.py file specifies what the path should be. There is a prefix inherited from the parent URL file.

 

7. Cart design, CartItem model


Use the command startappcarts to create two tables cart and cart_item in the same app as the cart. Customize the carts /models.py file with the following new classes:

class Cart(models.Model):

cart_id = models.CharField(max_length=250, blank=True)

date_added = models.DateTimeField(auto_now_add=True)

def __str__(self):

return self.cart_id

class CartItem(models.Model):

product = models.ForeignKey(Product, on_delete=models.CASCADE)

cart = models.ForeignKey(Cart, on_delete=models.CASCADE)

quantity = models.IntegerField()

is_active = models.BooleanField(default=True)

def __str__(self):

return self.product

そして、スーパーユーザーが管理するコードをcarts /admin.pyファイルに追加します。

admin.site.register(Cart)

admin.site.register(CartItem)

The cart table has records that describe a user's shopping cart, including both logged-in users and successful users (records are generated based on cookies on the local machine).

The CartItem table with the corresponding record is the item in the cart. The foreign key uses the product and with the cart.

Customize the urlpartterns variable in your cart / urls.py file as follows:

urlpatterns = [

path('', views.cart, name='cart'),

path('add_cart/<int:product_id>/', views.add_cart, name='add_cart'),

path('remove_cart/<int:product_id>/', views.remove_cart, name='remove_cart'),

path('remove_cart_item/<int:product_id>/', views.remove_cart_item, 

name='remove_cart_item'),

8. Home, store, product_detail templates


Go to the settings.py page and customize the TEMPLATES variable for the key/value pair as follows:

'DIRS': ['templates']

Use manager.py to create a folder at the same level as the template so that Django can automatically find it and load the template file. From the greatkart / views.py file, add a home function to create a request navigation function.

def home(request):

products = Product.objects.all().filter(is_available=True)

context = {'products': products,}

return render(request, 'home.html', context=context)

From the Templates folder, create a base.html file as the base template file for most pages in your system. And a home.html file as the home page.

 

9. Customize user models, categories, and product models


With Django, you can tackle a large number of tasks very quickly and easily. Makes software development in Python cheap and easy.

It also simplifies data serialization and delivery in XML or JSON format. This is useful when you want to create a web service or website that purely provides the data used by other websites or applications.

In summary, the Django framework is one of the best Python web frameworks available on the market for free and simple.

 

If you are considering offshore development, please feel free to contact us.

Here is our contact information.

Account Manager: Quan (Japanese/English available)

Phone number: (+84) 2462 900 388

Email: contact@hachinet.com

Please feel free to contact us for consultation/application by phone.

Click here for more information ▶