How to build an e-commerce shop with Python, Django, & Wagtail

“D-J-A-N-G-O. The D is silent.”

“D-J-A-N-G-O. The D is silent.”

Man, I love that line. So badass.

But the eponymous character from Quentin Tarantino’s masterpiece isn’t the only badass Django in town.

So is the popular Python framework of the same name.

Today, I’m leaving the realm of JavaScript frameworks for a quick venture into Django e-commerce.

In this post, I’ll answer legitimate questions you might have when starting a new e-commerce project, such as:

Is Python the right language for my project? And Django the right framework? Which tools or plugins should I use?

Then, I’ll show you our homemade recipe for Django-powered e-commerce success with a step-by-step Wagtail CMS tutorial:

  • Creating a new Wagtail site.
  • Adding Snipcart configuration settings.
  • Generating database migrations.
  • Creating new products for your Django store.
  • Crafting an e-commerce template.

Let’s start with the basics.

The State of Python

One of the main reasons to pick Django as a framework is its Pythonfoundation.


A general purpose, dynamic programming language, Python was developed by ex-Googler Guido van Rossum in the late 80’s. A fan of Monthy Python, he took one-half of the name to baptize his programming project.

He wasn’t joking though. To say that Python has become “popular” is an understatement.

Today, it’s used by hundreds of thousands of developers all over the world. As StackOverflow puts it:

The term “fastest-growing” can be hard to define precisely, but we make the case that Python has a solid claim to being the fastest-growing major programming language.

A few reasons explain the Python love:

  • Its grammatical readability is awesome.
  • It has a fast learning curve for newcomers.
  • It boasts a long-lasting, solid ecosystem of libraries & community
  • It’s now the standard language for data science & machine learning.
  • It powers great dev tools like Pelican, a neat static blog generator.
  • Reddit is written in Python. ;)

What about the Django framework?

Django is an open source, high-level Python web framework. Its emphasis on reusable components makes it faster for developers to build web apps on top of Python. It presents itself as a web framework for perfectionists with deadlines.

Now maintained by the Django Software Foundation, it was originally written by two brilliant Lawrence Journal-World developers. Oh, and while Python draws its name from comedy icons, Django got his from a versatile guitar legend: Django Reinhardt!

As a full-stack framework, it overshadows pretty much any alternative tool out there. It’s fast, fully loaded, secure, scalable & versatile. All characteristics you’ll probably want to apply to your e-commerce setup!

Why use Django for e-commerce?

While you can do a lot with Django, let’s keep the focus on what it brings to e-commerce and the different tools available to put together an online store.


First, here are some Django features to consider if you’re looking for the right framework to build a shop.

→ Scalability

Django is perfect for e-commerce startups, as it’s a good fit for small websites, but also has scales perfectly with business growth. You can rely on Django to handle hundreds/thousands of visitors at a time. It’s built with independent components you can unplug or replace depending on your needs at any specific time.

→ Security

With e-commerce, you want to make sure merchants and clients alike feel safe through your shopping experience. Django prevents a whole lot of common security mistakes which often are what weakens traditional PHP CMSs. For instance, Django hides your site’s source code from direct viewing on the web by dynamically generating web pages.

→ Feature-rich

Compared to most frameworks, Django comes with way more features out-of-the-box. It allows you to build an app right off the bat. Perfect for supporting your online store with functionalities such as user authentification, content management or RSS feed. If something seems to be missing, you can count on Django’s community and plugins ecosystem to extend your app!

→ SEO-friendly

SEO is paramount for any online business. While other frameworks don’t natively play well with search engines (mainly JavaScript frameworks, like Vue or React), at least Django advocates best practices for SEO. Human-readable URLs and sitemap features are sure to please any marketing team.

Oh and also, it’s fast. Which is always great for both customer experience and SEO.

→ Reliable

It has been crowd-tested for a while now, and the community surrounding it is largely supportive. It’s continuously updated by active developers; maybe you’ll even find yourself contributing. ;)

There are a few noteworthy e-commerce solutions in the Python/Django ecosystem:

  • Oscar — Domain-driven e-commerce for Django, open-source.
  • Saleor — An e-commerce storefront written in Python, open-source.
  • Django-SHOP — A Django based shop system.
  • Shuup — A single and multi-vendor application.

You can explore more options through this extensive list of the best e-commerce packages.

Now let me present you another cool stack for a complete and custom e-commerce setup with Django.

Wagtail CMS + Snipcart e-commerce setup


Wagtail is a developer-first Django content management system. Free and open source, it was developed by the good-hearted folks at Torchbox. It’s elegant, flexible, and, IMHO, kicks ass.

In the following Wagtail tutorial, the CMS will be in charge of creating and managing products that users will then be able to buy through a shopping cart.

By the end of it, you’ll have a solid Django-powered e-commerce site up and running.

Let’s get practical!

Django e-commerce tutorial with Wagtail CMS

To continue with the movie references and because we’re working in Python, I’ll craft a Slytherin demo shop! Let’s see how it goes.

Pre-requisites

1. Creating a new Wagtail e-commerce site

Make sure you have Wagtail installed. If not, refer to their installation documentation.


Open a terminal and launch a new Wagtail site:

wagtail start snipcartwagtaildemocd snipcartwagtaildemoz

wagtail start snipcartwagtaildemo
cd snipcartwagtaildemo

We have an extra step to complete the Wagtail setup, and it’s to install the wagtail.contrib.settings plugin that we'll require later on.

In your new Wagtail project, open the base.py file located in settingsfolder. Then, add wagtail.contrib.settings to the INSTALLED_APPS array.

# ./setting/base.py
	INSTALLED_APPS = [
	    ...,
	    'wagtail.contrib.settings'
	]

1.1 Models definition

The first thing you need to do is create your Page models. Wagtail uses these Django models to generate a page type.


Open the models.py file located in the home folder of your product. This is where you'll define all your custom models.

Create two different models:

  • Product: defines the product you're selling.
  • ProductCustomField: defines a single product custom field.

Let’s begin by importing required modules:

# ./home/models.py
	from django.db import models
from modelcluster.fields import ParentalKey


from wagtail.core.models import Page, Orderable
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel
from wagtail.images.edit_handlers import ImageChooserPanel

Now add the Product model:

# ./home/models.py

class Product(Page):
    sku = models.CharField(max_length=255)
    short_description = models.TextField(blank=True, null=True)
    price = models.DecimalField(decimal_places=2, max_digits=10)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )


    content_panels = Page.content_panels + [
        FieldPanel('sku'),
        FieldPanel('price'),
        ImageChooserPanel('image'),
        FieldPanel('short_description'),
        InlinePanel('custom_fields', label='Custom fields'),
    ]

And ProductCustomField:

# ./home/models.py

class ProductCustomField(Orderable):
    product = ParentalKey(Product, on_delete=models.CASCADE, related_name='custom_fields')
    name = models.CharField(max_length=255)
    options = models.CharField(max_length=500, null=True, blank=True)


    panels = [
        FieldPanel('name'),
        FieldPanel('options')
    ]

2. Adding Snipcart configuration settings

If you need more help for this part, refer to our documentation here and here.

Let’s make sure you can update the Snipcart API key directly from Wagtail’s dashboard. You’ll need to add site settings to do so.

Site settings are special fields that you can add to your models file. They’ll appear in the Wagtail Settings section of the dashboard.

Import this module:

# ./home/models.py

from wagtail.contrib.settings.models import BaseSetting, register_setting

Then add these:

# ./home/models.py

@register_setting
class SnipcartSettings(BaseSetting):
    api_key = models.CharField(
        max_length=255,
        help_text='Your Snipcart public API key'
    )

3. Database migrations

Now that your models are created, you’ll need to generate database migrations and run them.


In your terminal, use the makemigrations command:

manage.py makemigrations

You should see the following output:

Migrations for 'home':
home\migrations\0003_product_productcustomfield_snipcartsettings.py
- Create model Product
- Create model ProductCustomField
- Create model SnipcartSettings

Once the migrations are generated, apply them on your database with the migrate command:

	manage.py migrate

It will take a couple of seconds; Wagtail will set up its own database schema along with the models you just defined.

Finally, create your first CMS user with the createsuperuser command:

manage.py createsuperuser

Don’t forget the username and password you picked — you will need them to log into Wagtail’s dashboard.

4. Creating products

Start by firing up your dev server with the Django dev server command:

manage.py runserver

Now open your browser and navigate to: http://localhost:8000/admin. Use the credentials you set up earlier to log in.

Select the Home page in Wagtail's menu. Then click on the Add child page button.

You’ll be asked to pick a type of page, select Product.

Enter the product details, then publish your new product:

You can create as many products as you wish.

4.1 Adding Snipcart API key

Remember the SnipcartSettings class you created? You'll be able to configure your API key by expanding the Settings menu and going to Snipcart settings.

Open Snipcart’s dashboard and get your public API key (Test or Live). Go back to Wagtail and paste it in the API key field.

Save your settings.

5. Templating

Your backend is now ready, your API key is configured, and your first products are created. Time to start building the site.


For this demo, I decided to use Spectre.css CSS framework. It’s straightforward and lightweight.

Open the base.html file located in snipcartwaigtaildemo/templates.

You’ll need to add references for Spectree.css and Snipcart. Add these lines in the head of your document:

<!-- ./snipcartwagtaildemo/templates/base.html -->
{% load static wagtailsettings_tags %}
{% get_settings %}

{# Global stylesheets #}


&lt;link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css"&gt;
&lt;link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre-exp.min.css"&gt;
&lt;link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre-icons.min.css"&gt;


{# Snipcart #}


{% if settings.home.SnipcartSettings.api_key %}
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.snipcart.com/scripts/2.0/snipcart.js" id="snipcart" data-api-key="{{ settings.home.SnipcartSettings.api_key }}"&gt;&lt;/script&gt;
    &lt;link href="https://cdn.snipcart.com/themes/2.0/base/snipcart.min.css" type="text/css" rel="stylesheet" /&gt;
{% endif %}

The Snipcart API key that you configured previously is available via:

settings.home.SnipcartSettings.api_key

Then, add the navbar and some other Spectre.css layout elements.

Replace the content of the whole body by these lines:

<!-- ./snipcartwagtaildemo/templates/base.html -->
{% wagtailuserbar %}

&lt;div class="container grid-lg"&gt;
    &lt;header class="navbar"&gt;


        &lt;section class="navbar-section"&gt;
            &lt;a href="/" class="navbar-brand mr-2"&gt;
                Products
            &lt;/a&gt;
        &lt;/section&gt;


        &lt;!-- Snipcart summary and View cart button --&gt;
        &lt;section class="navbar-section snipcart-summary"&gt;
            &lt;div class="input-group input-line"&gt;
                &lt;a href="" class="btn btn-primary snipcart-checkout"&gt;
                    &lt;i class="icon icon-apps"&gt;&lt;/i&gt;
                    View cart (&lt;span class="snipcart-total-items"&gt;0&lt;/span&gt;)
                &lt;/a&gt;
            &lt;/div&gt;
        &lt;/section&gt;


    &lt;/header&gt;
&lt;/div&gt;


&lt;div class="container grid-lg"&gt;
    {% block content %}{% endblock %}
&lt;/div&gt;


{# Global javascript #}
&lt;script type="text/javascript" src="{% static 'js/snipcartwagtaildemo.js' %}"&gt;&lt;/script&gt;


{% block extra_js %}
    {# Override this in templates to add extra javascript #}
{% endblock %}

5.1 Listing products

The first template you need is your index, where products will be listed.


You’ll have to make your products available in your home page context. In any Wagtail Page, you can override a method name get_context.

You can add the data that the view will receive in parameters. In my case, I want to set the products context variable.

Open the models.py file in home folder and update the HomePage class:

# ./home/models.py

class HomePage(Page):
    def get_context(self, request):
        context = super().get_context(request)


        context['products'] = Product.objects.child_of(self).live()


        return context

Then, open the home_page.html file located in the home/templates/homefolder.

Let’s create a simple page that will show each product image with a link to the product details.

<!-- /.home/templates/home/home_template.html -->
{% extends "base.html" %}
{% load wagtailimages_tags %}

{% block content %}
    &lt;h1&gt;
        Welcome to our store
    &lt;/h1&gt;


    &lt;div class="columns"&gt;
        {% for product in products %}
            &lt;div class="column col-6"&gt;
                &lt;div class="card"&gt;
                    &lt;div class="card-image"&gt;
                        {% image product.image fill-1000x200 as tmp_image %}
                        &lt;img src="{{ tmp_image.url }}" alt="" class="img-responsive"&gt;
                    &lt;/div&gt;
                    &lt;div class="card-header"&gt;
                        &lt;a href="{{ product.get_url }}" class="btn btn-primary float-right"&gt;
                            &lt;i class="icon icon-plus"&gt;&lt;/i&gt;
                        &lt;/a&gt;
                        &lt;div class="card-title h5"&gt;
                            {{ product.title }}
                        &lt;/div&gt;
                    &lt;/div&gt;
                    &lt;div class="card-body"&gt;
                        {{ product.description }}
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        {% endfor %}
    &lt;/div&gt;
{% endblock %}

5.2 Product details

The last template is the one showing individual product details along with the Snipcart buy button.


Also, it would be nice to be able to select product options directly on this page, before adding it to the cart. So I’ll add a way to choose all custom fields with options directly in the template.

Before writing some HTML, you have to update the view context. Django templates don’t give us 100% access to all Python methods and objects, so things like splitting a string do not work very well.

I decided to override the get_context method again. Maybe there's a better way to do that—let me know in the comments below! ;)

Open models.py from the home folder and add this method in the Productclass:

# ./home/models.py

class Product(Page):


    def get_context(self, request):
        context = super().get_context(request)
        fields = []
        for f in self.custom_fields.get_object_list():
            if f.options:
                f.options_array = f.options.split('|')
                fields.append(f)
            else:
                fields.append(f)


        context['custom_fields'] = fields


        return context

A custom_fields array will be available in the product.html template.

Create a file named product.html in home/templates/home folder. This is the template that will be associated with the Product page model.

<!-- ./home/templates/home/product.html -->
{% extends "base.html" %}
{% load wagtailimages_tags %}

{% block content %}
    &lt;div class="container grid-lg"&gt;
        &lt;div class="columns"&gt;
            &lt;div class="column col-4"&gt;
                {% image page.image max-300x300 as temp_image %}
                &lt;img src="{{ temp_image.url }}" alt="" /&gt;
            &lt;/div&gt;
            &lt;div class="column col-8"&gt;
                &lt;h1&gt;
                    {{ page.title }}
                &lt;/h1&gt;


                &lt;p&gt;
                    {{ page.short_description }}
                &lt;/p&gt;


                &lt;p&gt;
                    {% for f in custom_fields %}
                        {% if f.options_array|length &gt; 0 %}
                            &lt;div class="form-group"&gt;
                                &lt;label class="form-label" for="{{ f.name|lower }}"&gt;
                                    {{ f.name }}
                                &lt;/label&gt;
                                &lt;select class="form-select custom-field-select" id="{{ f.name|lower }}" data-field="{{ forloop.counter }}"&gt;
                                    {% for opt in f.options_array %}
                                        &lt;option&gt;
                                            {{ opt }}
                                        &lt;/option&gt;
                                    {% endfor %}
                                &lt;/select&gt;
                            &lt;/div&gt;
                        {% endif %}
                    {% endfor %}
                &lt;/p&gt;


                &lt;button class="snipcart-add-item btn btn-primary"
                    data-item-name="{{ page.title }}"
                    data-item-id="{{ page.sku }}"
                    data-item-url="{{ page.get_full_url }}"
                    data-item-price="{{ page.price }}"
                    data-item-description="{{ page.short_description}}"
                    data-item-image="{{ temp_image.url }}"
                    {% for f in custom_fields %}
                        data-item-custom{{forloop.counter}}-name="{{f.name}}"
                        data-item-custom{{forloop.counter}}-options="{{f.options}}"
                    {% endfor %}&gt;
                    &lt;i class="icon icon-plus"&gt;&lt;/i&gt;
                    Add to cart
                &lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
{% endblock %}

Then, add some JavaScript to update the Snipcart buy button when a custom field selection is made on the page.

Add the following script snippet before the endblock statement:

<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.custom-field-select').onchange = function(event) {
if (event.target.dataset.field) {
document.querySelector('.snipcart-add-item')
.dataset['itemCustom' + event.target.dataset.field + 'Value'] = event.target.value;
}
};
},false);
</script>

This code updates the button data attributes when the select value changes.

If you click on the + button beside any product, you should see its details:

You now have pretty strong foundations to start your e-commerce project using Django and Wagtail!

These frameworks are very powerful. You could quickly add some search functionalities, product suggestions, reviews, etc.

Live demo & GitHub repo

See the live demo
See the GitHub repo

Closing thoughts

I really enjoyed working with Wagtail, as it’s simple and intuitive. I have to say that their documentation feels incomplete at times, though. At first, I wanted to make some changes on how routing would work and haven’t found anything in their docs about that.


I didn’t have Python installed on my laptop at the start, so setting up everything and having this demo up and running took me about a day, including hosting the demo. I figure it would be way faster for avid Python developers!

For further exploration, I think Wagtail could be a great headless CMS, especially with their built-in API. I think it could be cool to leverage it and strap it to tools like Nuxt or Gatsby to handle the front end.


By : Charles Ouellet
























Python GUI Programming Projects using Tkinter and Python 3

Python GUI Programming Projects using Tkinter and Python 3

Python GUI Programming Projects using Tkinter and Python 3

Description
Learn Hands-On Python Programming By Creating Projects, GUIs and Graphics

Python is a dynamic modern object -oriented programming language
It is easy to learn and can be used to do a lot of things both big and small
Python is what is referred to as a high level language
Python is used in the industry for things like embedded software, web development, desktop applications, and even mobile apps!
SQL-Lite allows your applications to become even more powerful by storing, retrieving, and filtering through large data sets easily
If you want to learn to code, Python GUIs are the best way to start!

I designed this programming course to be easily understood by absolute beginners and young people. We start with basic Python programming concepts. Reinforce the same by developing Project and GUIs.

Why Python?

The Python coding language integrates well with other platforms – and runs on virtually all modern devices. If you’re new to coding, you can easily learn the basics in this fast and powerful coding environment. If you have experience with other computer languages, you’ll find Python simple and straightforward. This OSI-approved open-source language allows free use and distribution – even commercial distribution.

When and how do I start a career as a Python programmer?

In an independent third party survey, it has been revealed that the Python programming language is currently the most popular language for data scientists worldwide. This claim is substantiated by the Institute of Electrical and Electronic Engineers, which tracks programming languages by popularity. According to them, Python is the second most popular programming language this year for development on the web after Java.

Python Job Profiles
Software Engineer
Research Analyst
Data Analyst
Data Scientist
Software Developer
Python Salary

The median total pay for Python jobs in California, United States is $74,410, for a professional with one year of experience
Below are graphs depicting average Python salary by city
The first chart depicts average salary for a Python professional with one year of experience and the second chart depicts the average salaries by years of experience
Who Uses Python?

This course gives you a solid set of skills in one of today’s top programming languages. Today’s biggest companies (and smartest startups) use Python, including Google, Facebook, Instagram, Amazon, IBM, and NASA. Python is increasingly being used for scientific computations and data analysis
Take this course today and learn the skills you need to rub shoulders with today’s tech industry giants. Have fun, create and control intriguing and interactive Python GUIs, and enjoy a bright future! Best of Luck
Who is the target audience?

Anyone who wants to learn to code
For Complete Programming Beginners
For People New to Python
This course was designed for students with little to no programming experience
People interested in building Projects
Anyone looking to start with Python GUI development
Basic knowledge
Access to a computer
Download Python (FREE)
Should have an interest in programming
Interest in learning Python programming
Install Python 3.6 on your computer
What will you learn
Build Python Graphical User Interfaces(GUI) with Tkinter
Be able to use the in-built Python modules for their own projects
Use programming fundamentals to build a calculator
Use advanced Python concepts to code
Build Your GUI in Python programming
Use programming fundamentals to build a Project
Signup Login & Registration Programs
Quizzes
Assignments
Job Interview Preparation Questions
& Much More

Guide to Python Programming Language

Guide to Python Programming Language

Guide to Python Programming Language

Description
The course will lead you from beginning level to advance in Python Programming Language. You do not need any prior knowledge on Python or any programming language or even programming to join the course and become an expert on the topic.

The course is begin continuously developing by adding lectures regularly.

Please see the Promo and free sample video to get to know more.

Hope you will enjoy it.

Basic knowledge
An Enthusiast Mind
A Computer
Basic Knowledge To Use Computer
Internet Connection
What will you learn
Will Be Expert On Python Programming Language
Build Application On Python Programming Language

Python Programming Tutorials For Beginners

Python Programming Tutorials For Beginners

Python Programming Tutorials For Beginners

Description
Hello and welcome to brand new series of wiredwiki. In this series i will teach you guys all you need to know about python. This series is designed for beginners but that doesn't means that i will not talk about the advanced stuff as well.

As you may all know by now that my approach of teaching is very simple and straightforward.In this series i will be talking about the all the things you need to know to jump start you python programming skills. This series is designed for noobs who are totally new to programming, so if you don't know any thing about

programming than this is the way to go guys Here is the links to all the videos that i will upload in this whole series.

In this video i will talk about all the basic introduction you need to know about python, which python version to choose, how to install python, how to get around with the interface, how to code your first program. Than we will talk about operators, expressions, numbers, strings, boo leans, lists, dictionaries, tuples and than inputs in python. With

Lots of exercises and more fun stuff, let's get started.

Download free Exercise files.

Dropbox: https://bit.ly/2AW7FYF

Who is the target audience?

First time Python programmers
Students and Teachers
IT pros who want to learn to code
Aspiring data scientists who want to add Python to their tool arsenal
Basic knowledge
Students should be comfortable working in the PC or Mac operating system
What will you learn
know basic programming concept and skill
build 6 text-based application using python
be able to learn other programming languages
be able to build sophisticated system using python in the future

To know more: