Skip to content

Commit

Permalink
Merge pull request awesto#424 from jrief/develop
Browse files Browse the repository at this point in the history
Version 0.9.2
  • Loading branch information
jrief authored Sep 29, 2016
2 parents 8ccbcc9 + 547e9f7 commit 405df11
Show file tree
Hide file tree
Showing 63 changed files with 1,013 additions and 50,485 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ database.db
OLD-out-of-date
.tox
workdir/
django-shop-workdir_*
node_modules/
bower_components/
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ env:

install:
- pip install tox
- npm install

script:
- "if [[ $TRAVIS_PYTHON_VERSION == '2.7' && $DJANGOVER ]]; then export TOX_ENV=py27-$DJANGOVER; fi"
Expand Down
7 changes: 4 additions & 3 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
Changelog for djangoSHOP
========================

0.9.2.dev
=========
0.9.2
=====

* Minimum required version of django-filer is now 1.2.5.
* Minimum required version of djangocms-cascade is now 0.10.0.
* Minimum required version of djangocms-cascade is now 0.10.2.
* Minimum required version of djangoshop-stripe is now 0.2.0.
* Changed the default address models to be more generic. Please read the
:doc:`upgrade instructions <upgrading>` if you are upgrading from 0.9.0 or 0.9.1.
* Fixed :py:meth:`shop.money.fields.decontruct` to avoid repetitive useless generation of migration
Expand Down
24 changes: 12 additions & 12 deletions docs/tutorial/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Prepare the Installation
========================

To run the examples shown in this tutorial, you must install **django-shop** from GitHub, since
the pip-installable from PyPI only contains the main files. Before proceeding, please make sure
virtualenv_ is installed on your system, otherwise you would pollute your Python site-packages
folder.
the pip-installable from PyPI only contains the framework but not the files required for the demos.
Before proceeding, please make sure virtualenv_ is installed on your system, otherwise you would
pollute your Python site-packages folder.

Also ensure that these packages are installed using the favorite package manager of your operating
system:
Expand All @@ -30,8 +30,7 @@ system:
* Redis: http://redis.io/
* SQLite: https://www.sqlite.org/
* Node Package Manager: https://www.npmjs.com/
* Python 2.7 (Latest minor version recommended)
* Django 1.9 (Latest minor version recommended)
* Python 2.7 or 3.4 and later

Note: replace ``requirements/common.txt`` with ``requirements/py2.txt`` below
if you want to use Python 2. We recommend that you use Python 3.
Expand All @@ -47,10 +46,11 @@ if you want to use Python 2. We recommend that you use Python 3.
(shoptutorial)$ pip install -r requirements/common.txt
(shoptutorial)$ npm install
These statements will setup an environment that runs a demo shop out of the box.
These statements will setup an environment that runs one of the demo shops out of the box.

You may populate the database with your own products, or if impatient, :ref:`tutorial/quickstart`
using prepared CMS page layouts, products and media files.
If you want to populate the database with your own categories, products and pages, proceed as
described below. Otherwise, or if impatient, you may :ref:`tutorial/quickstart` using prepared
CMS page layouts, products and media files.


.. _tutorial/create-demo-database:
Expand All @@ -63,7 +63,7 @@ Finally we must create a database to run our example project:
.. code-block:: shell
(shoptutorial)$ cd example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=polymorphic DJANGO_DEBUG=1
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=commodity
(shoptutorial)$ ./manage.py migrate
(shoptutorial)$ ./manage.py createsuperuser
Email address: [email protected]
Expand All @@ -81,9 +81,9 @@ Finally point a browser onto http://localhost:8000/ and log in as the superuser
Add some pages to the CMS
=========================

In **djangoSHOP**, every page, with the exception of the product's detail pages, can be rendered by
the CMS. Therefore, unless you need a special landing page, start immediately with the *Catalog List
View* of your products. Change into the Django Admin backend, chose the section
In **djangoSHOP**, every page, can be rendered by the CMS. Therefore, unless you need a special
landing page, start immediately with the *Catalog's List View* of your products. Change into the
Django Admin backend, chose the section

**Start > django CMS > Pages**

Expand Down
216 changes: 100 additions & 116 deletions docs/tutorial/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,161 +4,145 @@
Quickstart a Running Demo
=========================

Using a Docker image
====================
Running Demos Locally
=====================

To get a first impression of the **djangoSHOP** examples, you may use a prepared Docker container.
If not already available on your workstation, first install the `Docker runtime environment`_ and
start a Docker machine.
You may download all dependencies and start the testing projects manually. If you want to use the
demo as a starting point for your own project, then this presumably is the better solution.

Now you may run a fully configured **djangoSHOP** image on your local machine:

.. code-block:: bash
docker run -p 9001:9001 jrief/myshop-sample:latest
This image is rather large (1.9 GB) therefore it may take some time to download.

Locate the IP address of the running container using ``docker-machine ip default``. Then point
a browser onto this address using port 9001, for instance http://192.168.99.100:9001/en/

Please note that before the server starts, a full text index is built and the images are thumbnailed.
This takes additional time. Therefore, if you stop the running container, before rerunning the
Docker image it is recommended to restart the container. First locate it using

.. code-block:: bash
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
79b7b69a7473 jrief/myshop-sample:latest "/usr/sbin/uwsgi --in" 11 minutes ago
...
$ docker start 79b7b69a7473
and then restart it. The access the administration backed, sign in as user "*admin*" with
password "*secret*".

.. note:: This demo does not function with the Payment Service Provider Stripe, because each
merchant requires its own credentials. The same applies for sending emails, because
the application requires an outgoing SMTP server.


The Classic Approach
====================

Alternatively you may also download all dependencies and start the project manually. If you want to
use the demo as a starting point, this presumably is the better solution.

Filling your CMS with page content and adding products is a boring job. Impatient users may start
five demos using prepared sample data. First assure that all dependencies are installed into its
virtual environment as described in section ":ref:`tutorial/prepare-installation`". Then instead of
adding pages and products manually, `download the media files`_ and unpack them into the folder
``django-shop``:
Filling your CMS with page content and adding products is a boring job. Impatient users can start
with one of the five provided demos, using prepared sample data. First assure that all dependencies
are installed into it's virtual environment as described in section :ref:`tutorial/prepare-installation`.
Then instead of adding pages and products manually, use the following steps:

.. code-block:: shell
(shoptutorial)$ tar zxf DOWNLOAD/FOLDER/django-shop-workdir.tar.gz
(shoptutorial)$ cd django-shop/example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=commodity
(shoptutorial)$ ./manage.py initialize_shop_demo
(shoptutorial)$ ./manage.py runserver
Starting from this folder, you can run all five demos:
Point a browser onto http://localhost:8000/admin/ and sign in as user *admin* with password
*secret*.

The first, simple demo shows how to setup a monolingual shop, with a generic product, which
is named a "Commodity".
This runs the demo for :ref:`tutorial/commodity`.

The second, internationalized demo shows how to setup the same shop, but multilingual. For
translating the model attributes, this installation uses django-parler_ app.
.. note:: The first time, **djangoSHOP** renders a page, images must be thumbnailed and cropped.
This is an expensive operation which runs only once. Therefore please be patient, when loading
pages for the first time.

The third demo shows how to declare your own product model, using Smart Cards as an example.
Starting from this folder, you can run all five demos by reconfiguring the environment variable
``DJANGO_SHOP_TUTORIAL``. Allowed values are ``commodity``, ``i18n_commodity``, ``smartcard``,
``i18n_smartcard`` and ``polymorphic``. Afterwards re-run ``./manage.py initialize_shop_demo``
for each of them.

The fourth demo is the same as the third one, but internationalized.
.. note:: All demos can be started independently from each other, but you are encouraged to begin
with the ``commodity`` example, and then proceed to the more complicate ones.

The fifth demo combines all of the above, and uses polymorphism_ to distinguish between various
types of products. This demo is multilingual and handles Commodities, Smart Cards and Smart Phones
with variations.
.. _tutorial/commodity:

.. note:: All demos can be started independently from each other, but you are encouraged to start
with the first example, and then proceed to the more complicate ones.
The Commodity Product Model
---------------------------

.. _download the media files: http://downloads.django-shop.org/django-shop-workdir.tar.gz
.. _django-parler: http://django-parler.readthedocs.org/en/latest/
.. _polymorphism: https://django-polymorphic.readthedocs.org/en/latest/
The ``commodity`` demo shows how to setup a monolingual shop, with a generic product, named
**Commodity**. The product model :class:`shop.models.defauls.commodity.Commodity` is part of the
**djangoSHOP** framework. It is intended for shops where the merchant does not want to create a
customized product model, but rather prefers to create the product's detail views using common CMS
functionality.

A **Commodity** model contains only the following attributes:

Simple Generic Product (Commodity) Demo
=======================================
* The name of the product
* The product code
* The slug (a short label used as the last bit in the URLs)
* The product's unit price
* One sample image to be shown in the catalog's list view
* A caption to be shown in the catalog's list view

Assure you are in the ``django-shop`` folder and using the correct virtual environment. Then in a
shell invoke:
The detail view for each product must however be styled individually using a DjangoCMS placeholder
together with the plugin system provided by djangocms-cascade_. This gives the merchant all the
flexibility to style each product's detail page individually and without having to create a special
HTML template. Into the provided placeholder we then can add as many text fields as we want.
Additionally we can use image galleries, carousels, different backgrounds, tab sets, etc.

.. code-block:: shell
One plugin which should always be present is the **Add Product to Cart** plugin as found in section
**Shop**, otherwise a customer wouldn't be able to add that product to the cart and thus purchasing
anything.

(shoptutorial)$ cd example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=commodity DJANGO_DEBUG=1
(shoptutorial)$ ./manage.py migrate
(shoptutorial)$ ./manage.py loaddata fixtures/myshop-commodity.json
(shoptutorial)$ ./manage.py runserver
Using the **Commodity** product model only makes sense, if the merchant does not require special
product attributes and normally is only suitable for shops with up to a dozen articles. Otherwise,
creating a reusable HTML template is probably less effort, than filling the placeholder for each
product's detail page individually.

Point a browser onto http://localhost:8000/admin/ and sign in as user "*admin*" with password
"*secret*".

This runs the demo for :ref:`tutorial/simple-product`.
The Internationalized Commodity Product Model
---------------------------------------------

The ``i18n_commodity`` demo shows how to setup a shop, with the same generic product as in the
previous example, but with these attributes translatable into multiple natural languages:

Internationalized Products
==========================
* The name of the product
* The slug
* A caption to be shown in the catalog's list view

In this demo the description of the products can be translated into different natural languages.
All other product attributes from our **Commodity** model are shared across all languages.

When migrating from the Smart Card demo, assure you are in the ``django-shop`` folder and
using the correct virtual environment. Then in a shell invoke:
Using this internationalized configuration, requires to additionally install django-parler_.

.. code-block:: shell

(shoptutorial)$ cp workdir/db-smartcard.sqlite3 workdir/db-i18n_smartcard.sqlite3
(shoptutorial)$ cd example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=i18n_smartcard DJANGO_DEBUG=1
(shoptutorial)$ ./manage.py migrate
(shoptutorial)$ ./manage.py runserver
The Smart Card Product Model
----------------------------

Alternatively, if you prefer to start with an empty database, assure that the file
``workdir/db-i18n_smartcard.sqlite3`` is missing. Then in a shell invoke:
The ``smartcard`` demo shows how to setup a shop with a model, created explicitly to describe a
certain type of product. Smart Cards have many different attributes such as their card type, the
manufacturer, storage capacity and the maximum transfer speed. Here it's the merchant's
responsibility to create the database model according to the physical properties of the product.

.. code-block:: shell
The class :class:`myshop.models.smartcard.SmartCard` therefore is not part of the shop's framework,
but rather in the merchant's implementation as found in our example.

(shoptutorial)$ cd example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=i18n_smartcard DJANGO_DEBUG=1
(shoptutorial)$ ./manage.py migrate
(shoptutorial)$ ./manage.py loaddata fixtures/myshop-i18n_smartcard.json
(shoptutorial)$ ./manage.py runserver
Creating a customized product model is only a few lines of declarative Python code. Additionally we
have to create a Django template using HTML. It however keeps us from having to build a page using
plugins, for each product item we want to offer. It also helps us to structure our products using
attributes rather than describing them in a free form.

Point a browser onto http://localhost:8000/admin/ and sign in as user "*admin*" with password
"*secret*".

This runs a demo for :ref:`tutorial/multilingual-product`.
The Internationalized Smart Card Model
--------------------------------------

The ``i18n_smartcard`` demo is a variation of the above example, with a few attributes translated
into multiple languages, namely ``caption`` and ``description``. The product name of a Smart Card
is international anyways and doesn't require to be translated into different langauges. Hence we
don't require a translatable field for the product name and it's slug.

Polymorphic Products
====================

In this demo we show how to handle products with different properties and in different natural
languages. This example can't be migrated from the previous demos, without loosing lots of
information. It is likely that you don't want to add the Smart Phones manually, it is suggested
to start using a fixture.
The Polymorphic Product Model
-----------------------------

This example shows how to add Smart Phones in addition to the existing Smart Cards. Assure you are
in the ``django-shop`` folder and using the correct virtual environment. Then in a shell invoke:
The ``polymorphic`` demo is a combination from all of the examples from above. Here we declare a
base product model using the class :class:`myshop.models.polymorphic.Product`. We also declare
common fields available in all of our different product types. These common fields are used to build
up the view displaying a list of all products.

.. code-block:: shell
The model classes for Smart Card, Smart Phone and a variation of Commodity then inherit from this
base product class. These models additionally can declare attributes required to describe the
physical properties of each product type. Since they vary, we also have to create special templates
for the detail views of each of them. Since Smart Phones allow product variations, we even must
adopt the template for adding the product to the cart.

(shoptutorial)$ rm workdir/db-polymorphic.sqlite3
(shoptutorial)$ cd example
(shoptutorial)$ export DJANGO_SHOP_TUTORIAL=polymorphic
(shoptutorial)$ ./manage.py migrate
(shoptutorial)$ ./manage.py loaddata fixtures/myshop-polymorphic.json
(shoptutorial)$ ./manage.py runserver

Point a browser onto http://localhost:8000/admin/ and sign in as user "*admin*" with password
"*secret*".
Use one of the demos as a starting point for your project
=========================================================

This runs a demo for :ref:`tutorial/polymorphic-product`.
Depending on the needs of your e-commerce site, the easiest approach to start with **djangoSHOP**
is to use the demo which is most similar to one of the five from above. Then by copying example,
create a repository of the merchant's implementation. Starting from a working example and gradually
modifying it until reaching your final goals, typically is much easier than starting from scratch.
It also is the preferred way during agile development.


.. _Docker runtime environment: https://docs.docker.com/windows/
.. _django-parler: http://django-parler.readthedocs.org/en/latest/
.. _polymorphism: https://django-polymorphic.readthedocs.org/en/latest/
.. _slug:
.. _djangocms-cascade: http://djangocms-cascade.readthedocs.io/en/latest/
8 changes: 4 additions & 4 deletions docs/tutorial/simple-product.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ emphasized earlier, **djangoSHOP** is not shipped with ready to use product
models. Instead the merchant must declare these models based on the products
properties. Lets have a look ar a model describing a typical Smart Card:

.. literalinclude:: /../example/myshop/models/smartcard.py
.. literalinclude:: /../example/myshop/models/smartcard/__init__.py
:caption: myshop/models/smartcard.py
:linenos:
:language: python
Expand All @@ -22,7 +22,7 @@ be part of our abstract model ``BaseProduct``.

Additionally a smart card has some product specific properties:

.. literalinclude:: /../example/myshop/models/smartcard.py
.. literalinclude:: /../example/myshop/models/smartcard/__init__.py
:linenos:
:language: python
:lines: 23-34
Expand All @@ -31,7 +31,7 @@ these class attributes depend heavily on the data sheet of the product to sell.

Finally we also want to position our products into categories and sort them:

.. literalinclude:: /../example/myshop/models/smartcard.py
.. literalinclude:: /../example/myshop/models/smartcard/__init__.py
:linenos:
:language: python
:lines: 34-40
Expand Down Expand Up @@ -84,7 +84,7 @@ Instead **djangoSHOP** is shipped with a special mixin class ``CMSPageAsCategory
handles the relation between CMS pages and the product. This however implies that the field used
to specify this relation is named ``cms_pages``.

.. literalinclude:: /../example/myshop/admin/smartcard/smartcard.py
.. literalinclude:: /../example/myshop/admin/smartcard.py
:linenos:
:language: python
:lines: 6-
Expand Down
3 changes: 2 additions & 1 deletion email_auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def validate_unique(self, exclude=None):
for them.
"""
super(User, self).validate_unique(exclude)
if self.email and get_user_model().objects.exclude(id=self.id).filter(is_active=True, email__exact=self.email).exists():
if self.email and get_user_model().objects.exclude(id=self.id).filter(is_active=True,
email__exact=self.email).exists():
msg = _("A customer with the e-mail address ‘{email}’ already exists.")
raise ValidationError({'email': msg.format(email=self.email)})
Loading

0 comments on commit 405df11

Please sign in to comment.