Shoop documentation

Contents

Getting Started with Shoop

Note

If you are planning on developing Shoop, read the other Getting Started guide instead.

Installation

Todo

Update this when Shoop is published to PyPI.

This guide assumes familiarity with the PyPA tools for Python packaging, including pip and virtualenv.

  1. Set up a new virtualenv for your Shoop project.

  2. Grab a Git clone of the Shoop sources. For this guide, we’ll assume the checkout of the clone lives in /stuff/shoop.

  3. Activate the virtualenv. Within the virtualenv, run

    pip install /stuff/shoop
    

This will install Shoop and its dependencies into your virtualenv.

After this, you can begin setting up a Django project using whichever standards you fancy.

Shoop Packages

Shoop is a constellation of Django apps, with many delivered in the single “Shoop Base” distribution, and with additional apps available as separate downloads.

The core package all Shoop installations will require is shoop.core. It contains the core business logic for e-commerce, and all of the database models required. However, it contains no frontend or admin dashboard, as different projects may wish to replace them with other components or even elide them altogether.

A default frontend, a basic but fully featured storefront, is included, as the application shoop.front. It itself has several sub-applications that may be used to toggle functionality on and off.

Todo

Describe the sub-apps.

A fully featured administration dashboard is also included as the application shoop.admin.

Change History

Shoop Release Notes

Shoop 3.0.0 Release Notes

Released on 2016-01-21 11:15 +0200.

Here’s a few highlights of new features, improvements and fixes in Shoop 3.0.0 since 2.0.0. For complete list of changes see Shoop Change Log or Git commit log.

There’s also update instructions for updating from 2.0.

New Features
  • Creating orders from the Admin
  • Localization
    • Provide tools for collecting and compiling translated messages.
    • Add language chooser to Classic Gray theme.
    • Implement JavaScript translations.
    • Xtheme plugins are now translatable.
    • More messages have been marked for translation.
    • Included translations: English, Finnish, Chinese and Japanese.
Improvements
  • Allow addons to inject resources to Xtheme templates
  • Enable email login and password recovery with username
  • Show product media at order history and product detail pages
  • Show Shoop version number in Admin
  • Xtheme editor improvements
  • Tax system improvements
    • Document the tax system (see Prices and Taxes in Shoop)
    • Implement override groups for Default Tax
    • Clean-up internal tax/price related APIs
  • And many more
Fixes
  • Xtheme: Don’t crash when trying to revert unsaved configuration
  • Default Tax: Fix calculation of added and compounded taxes
  • And many more
Miscellaneous
  • Test are now ran also on Travis
  • Python package dependencies are updated and not so strict anymore
  • Node package dependencies are locked down with npm-shrinkwrap
Updating from 2.0

Shoop 3.0 introduces some API changes which could affect projects or addons based on Shoop 2.0. Here is a list of the API changes and instructions how to update your code.

  • Priceful.total_price has been removed. This affects e.g. OrderLine, BasketLine and PriceInfo objects.
    • Use Priceful.price instead.
  • PriceTaxContext is removed.
    • You should not need it. Use PricingContext or TaxingContext where appropriate.
  • Default Theme is removed.
  • Address is split to MutableAddress and ImmutableAddress. Address is converted to abstract base class.
    • Database changes should be handled by migrations.
    • Usually usages of Address should be converted to MutableAddress, but they should be converted to immutable with Address.to_immutable for e.g. Order addresses.
  • Submodules of shoop.core.pricing are now private.
  • Submodules of shoop.core.order_creator are now private.
    • Use the API exposed by the module’s __init__.py.
  • shoop.core.utils.reference is removed.
  • Some submodules of shoop.xtheme are now private.
  • Submodules of shoop.core.models are now private.
    • Use the models or enums directly from the main package.
  • shoop.core.models.product_variation is removed.
    • Relevant functions are now available as Product methods.
Shoop 2.0.0 Release Notes

Released on 2015-10-05 16:45 +0300.

The highlights of this release (over 500 commits since 1.2!) are:

  • Revamp of the pricing and taxation systems for flexible international commerce
  • A new pluggable frontend theming system called Xtheme
  • Usability improvements for the admin, including much better media management
  • A brand new, slick frontend theme “Classic Gray”
  • Lots and lots of other fixes and improvements!

For more detailed list of changes see Shoop Change Log or Git commit log.

Shoop Change Log

Version 3.0.0

Released on 2016-01-21 11:15 +0200.

Core
  • Document Shoop tax system
  • API and documentation clean-up
  • Remove AddressManager
  • Split address into mutable and immutable address
  • Add Product.get_public_media helper function
  • Ensure TranslatabelShoopModel.__str__ doesn’t return lazy objects
  • Deny price unit changes of in-use Shop
  • Assign created customers to CustomerTaxGroups on creation
  • Fix couple tax related terms
  • Remove PriceTaxContext
  • Add PricingContextable interface and fix related docstrings
  • Remove Priceful.total_price
  • Add dynamic configuration API: shoop.configuration
  • Fix tax calculations and implement override groups
  • Add autoexpiring versioned cache API: shoop.core.cache
  • Enable email login and password recovery with username
Localization
  • Add translations for Finnish, Chinese and Japanese
  • Add translation extraction tools (shoop_makemessages)
  • Mark more messages for translation in templates
  • Enable JavaScript translations
Admin
  • Show Shoop version number in Admin
  • Fix order list sorting and filtering by total price
  • Fix CMS page list sorting by title
  • JavaScript compilation fixes: Turn our ES6 to ES5 with Babel
  • Fix URL encoding in redirect_to_login
  • Add view for creating orders from the Admin
  • Enable markdown editor for product and category description
  • Fix SKU and name initialization when creating a product by search
  • Add new template macros
  • Refactor templates to use template macros
  • Admin form styling and UX updates
Front
  • Set default country in checkout address forms
  • Fix SHOOP_FRONT_INSTALL_ERROR_HANDLERS setting being not respected
  • Change password recover error message
Xtheme
  • Make Xtheme plugins translatable
  • Allow addons to inject resources
  • Editor improvements
  • Fix a crash when trying to revert unsaved configuration
Classic Gray Theme
  • Show product media at order history and product detail pages
  • Add language changer to navigation
  • Add possibility for other future brand colors
  • Add carousel styles for Bootstrap carousel
  • Unvendor fonts
  • Show maintenance mode for super user
  • Fix logo text line height
  • Add new placeholders
  • Footer CMS Pages field are no longer required
  • Update label for footer links to avoid confusion
Default Theme
General/miscellaneous
  • Add Transifex configuration for the tx command
  • Add verbose names to all model and form fields
  • Do unit testing from doctests too
  • Update Python package dependencies
  • Lock down JavaScript dependencies
  • Code style improvements
  • Add configuration for Travis CI
  • Include JS and CSS source maps to the Python package
  • Cleanup tax TODOs
  • Move apply_request_middleware to testing
  • Documentation: Tune Sphinx settings and ignore migrations in API docs
  • Fix Eslint complaints
  • Make sure that bower is ran non-interactively
Version 2.0.0

Released on 2015-10-05 16:45 +0300.

Admin
  • Add basic Manufacturer views
  • Basic Supplier management
  • Add image field for category
  • Fix issue with price not being saved
  • Optionally disable creating shops
  • Add “Product Media” tab to product editing
  • Tabify translated fields
  • Variation UI styles
  • Media Browser Rehaul
  • Add ImageChoiceWidget
  • Actually send data-filter to media browser from browse widgets
  • Admin form error indicators
  • Add keyboard shortcuts to megasearch
  • Show first language tab with errors
  • Update styles for admin form error indicators
  • Show errors more clearly
  • Make folder clicks work at media browser
  • Fix paths of generated source maps
  • Add styles for bootstrap input-group
  • Time interval attribute now renders as DecimalField
  • Notify: Add better error handling for “step edit”-popup
  • Better variation error handling
  • Fix issue where visibility errors caused an error
  • Update admin category view
  • Admin datetimepicker
Core
  • Rework SimplePricing and pricing in general
  • Add non-ASCII support for supplier name
  • Fix checking of duplicate settings
  • Add new fields to shop core
  • Add DiscountPricingModule
  • Fix PriceInfo usage with non-one quantities
  • Fix shoop.core.migrations.0006
  • Tax clean-up and refactoring
  • Prevent Shop being deleted when image was deleted
Front
  • An all-new dynamic theming system, Xtheme
  • Classic Gray: A new slick theme built on the Xtheme system
  • Add ordering for cross sells template helper
  • Fix get_root_categories performance
  • Maintenance mode
  • template_helpers: Fix get_pagination_variables
  • Ensure user is logged in after activating account
  • Customer URL now requires login
  • Add support for Complex variations
  • Add Default ErrorHandling
  • Fix issue with variation children being listed for admin user
  • Front: Fix issue with variation children visible in search results
General/miscellaneous
  • Run ESLint on all the things!
  • Prunes, manifests
  • PEP8ify
  • Various fixes
  • Tests: Make test_user_detail_contact_seed not fail randomly
  • Miscellaneous tiny fixes
  • Fixes
  • Cms duplicate
  • Embetter patterns
  • Saner sanity tools
  • Workbench: Allow overriding couple settings from env
Version 1.2.0

Released on 2015-08-24 17:30 +0300.

  • Admin: Polyfill forms to ensure IE support
  • Fix uniqueness of some InternalIdentifierFields
    • Namely identifier field of Attribute, OrderStatus, ProductVariationVariable and ProductVariationVariableValue
  • Admin: Show payment details in order views
  • Coding Style: Clean-up and sort all imports
  • Fix usages of too-direct imports of models
  • Fix some unicode/bytes issues by adding “unicode_literals” imports
  • Admin layout fixes
    • Update telemetry admin layout and add translations tags
    • Change the attributes icon from product edit to the right one
    • Move attributes in product type edit to it’s own tab
    • Hide browser native horizontal scrollbar from main menu
  • Admin: Product image management
  • Admin: Product Variation management
  • Front: Add cross-sells to product detail page in default template
  • Admin: Fix menu scrolling
  • Upgrade Python and npm dependencies
  • Admin: Shop management
  • Front: Add link to admin panel in default template
  • Admin: Fix product attributes getting cleared unless they were edited
  • Admin: Product Sales Unit management
  • Admin: Add ProductChoiceWidget for selecting Products
  • Admin: Product cross-sell management
  • Admin: Styling: Add borders to bootstrap select
  • Admin: Fix showing details of a CompanyContact
  • Admin: Fix showing current addresses in contact details
Version 1.1.0

Released on 2015-07-03 12:30 +0300.

  • Improve “Getting Started with Shoop Development” documentation
  • Add a basic REST API for reading/writing products and reading orders
  • Use the database to store shopping baskets by default
  • Implement pluggable shopping basket storage backends
  • Implement basic contact group admin
  • Add telemetry (usage statistics) system
  • Add Dockerfile
  • Improve admin login flow
  • Document settings; make documentation builds available on ReadTheDocs
  • Make release packaging much more robust
  • Generate order keys in a secure manner
  • Trim admin search strings
  • Embetter admin order layouts
  • Create the Shop as active with shoop_init management command
  • Fix usages of Category.get_ancestors() in templates
  • Remove Stripe integration (shoop.stripe)
  • Core: Declare correct required_installed_apps in AppConfig
  • Fix handling of tuple-format required_installed_apps
  • Fix Money class to not read settings at instance creation
  • Fix management command shoop_show_settings for Python 3
  • Add Addon documentation (doc/addons.rst)
Version 1.0.0

Released on 2015-06-04 16:30 +0300.

  • The first Open Source version of Shoop.

Glossary

Software Components

Shoop
Shoop is a framework for building web shops or ordering portals.
Shoop Core
Shoop Core is the kernel of the Shoop. It is part of every Shoop installation.
Shoop Base
Shoop Base contains Shoop Core and optional modules.
Module

Todo

Define module

Todo

Define all plugin terms

Entities

user
user is general definition of any user
admin
admin is one kind of user
customer
Customer is one kind of user or one kind of company. Customer can be an admin and vice versa.
company
Company is one kind of organization. Organization is general definition of any group of companies and/or users.
shop

Todo

Define shop

Basic Administration Tasks

Todo

Revise this when user management lands in the admin.

You can use the built-in Django management commands createsuperuser and changepassword to manage superusers and change user passwords.

See also Creating superusers from Django’s documentation.

Prices and Taxes in Shoop

This document gives an overview of Shoop’s pricing and tax mechanics. For deeper view about the implementation – for example, if you’re implementing a price/tax related addon – also read the Implementation of Prices and Taxes in Shoop document.

Price Unit

Prices in Shoop have an unit that is combination of a currency and an includes/excludes taxes flag. That is, prices may be specified pretax or with taxes included. Which taxation type and currency is used is usually decided by the Shop, which has currency and prices_include_tax fields. In general, it is also possible that the active PricingModule uses a different price unit that is specified by the shop. Currently there is no such pricing module in the Shoop Base distribution.

Different price units cannot be mixed: Adding a pretax price and a price including taxes together would be an error, as would be adding USDs to EURs.

The price unit of a Shop can be changed as long as there are no Orders created for the shop.

The price unit of an Order is stored in its currency and prices_include_tax fields. The line prices of an order are stored in that unit, but the total price of order is stored with and without taxes in the taxful_price and taxless_price fields.

Calculation of Taxes

How Taxes Are Determined

Taxes in Shoop are implemented by a tax module. The Shoop Base distribution ships a tax module called Default Tax, but it is possible to plug in another tax module via addons or to implement a new one.

The responsibilities of a tax module are to calculate taxes for an order or for separate items (e.g. product, shipping or some other taxable item). The most important function of a tax module is to take an order source (such as a basket), which has lines (with pre-tax prices or prices with tax included) and fill in the taxes for each line in the source.

When Taxes Are Determined

Shoop calculates taxes for a basket in the confirmation phase of the checkout process or in the confirmation phase of the order creating UI in the Shop Admin. This means that taxes are not known for items in the basket, product listings or on the detail page of a product. The reason for not calculating taxes before the confirm phase is that the active tax module might query tax information from an external source which might be prohibitively slow or cost a transaction fee.

Todo

Update this documentation after SHOOP-1911 (Automatically calculating taxes if cheap) is implemented.

Taxes in Orders

Taxes are stored in order lines. Each order line can have several taxes applied and each of them is stored to a separate line tax object linked to the order line. These line tax objects contain references to Tax objects, the name of the tax, the applied amount and the base amount the tax is calculated off of.

The Default Tax Module

Shoop Default Tax is a tax module that calculates taxes based on a set of static rules stored in the database. A tax rule applies a tax for an order line or any other taxable item (e.g. product or shipping method). An item can be taxed with several taxes, which will be either added together or compounded over each other.

Defining Tax Rules for The Default Tax Module

The tax rules of Default Tax can be managed in the Shoop Shop Admin (MenuTaxesTax Rules).

Most fields of the tax rule determine the conditions when the rule applies. All non-empty fields must match for the rule to apply. Empty fields are not considered, e.g. if the “Customer tax groups” field is left empty, all customer tax groups will match. You may use these conditions to apply tax rules e.g. only for a specific country or area.

Area specific matching criteria fields are specified with a pattern that is able to match multiple values. See the help text in the admin view for details on how to write those patterns.

If all conditions of a tax rule match, the rule will be applied. That means that the tax specified in the rule will be added for the item. If there are several rules to be applied for an item, the total tax is determined by the priority field. Rules with same priorities are calculated as added (which would be the case for taxes in the United States) while rules with different priorities define compounding taxes (for example the PST taxes in Canada’s Quebec province).

Tax rules may also define override group numbers. If several rules match, only the rules with the highest override group number will be effective. This can be used, for example, to implement tax exemption by adding a rule with very high override group number that sets a zero tax.

Developer documentation

Getting Started with Shoop Development

Note

If you are planning on using Shoop for developing your own shop, read the other Getting Started guide instead.

Installation for Shoop Development

To start developing Shoop, you’ll need a Git checkout of Shoop and a Github fork of Shoop for creating pull requests. Github pull requests are used to get your changes into Shoop Base.

  1. If you haven’t done so already, create a fork of Shoop in Github by clicking the “Fork” button at https://github.com/shoopio/shoop and clone the fork to your computer as usual. See Github Help about forking repos for details.

  2. Setup a virtualenv and activate it. You may use the traditional virtualenv command, or the newer python -m venv if you’re using Python 3. See Virtualenv User Guide, if you don’t know virtualenv already. For example, following commands create and activate a virtualenv in Linux:

    virtualenv shoop-venv
    . shoop-venv/bin/activate
    
  3. Finally, you’ll need to install Shoop in the activated virtualenv in development mode. To do that, run the following commands in the root of the checkout (within the activated virtualenv):

    pip install -e .
    python setup.py build_resources
    

Workbench, the built-in test project

The Workbench project in the repository is a self-contained Django project set up to use an SQLite database. It is used by the test suite and is also useful for development on its own.

Practically the only difference to a normal Django project is that instead of python manage.py, one uses python -m shoop_workbench.

To get started with Workbench, invoke the following in the Shoop working copy root.

# Migrate database.
python -m shoop_workbench migrate

# Import some basic data.
python -m shoop_workbench shoop_populate_mock --with-superuser=admin

# Run the Django development server (on port 8000 by default).
python -m shoop_workbench runserver

You can use the credentials admin/admin, that is username admin and password admin to log in as a superuser on http://127.0.0.1:8000/ .

Building resources

Shoop uses JavaScript and CSS resources that are compiled using various Node.js packages. These resources are compiled automatically by setup.py when installing Shoop with pip, but if you make changes to the source files (e.g. under shoop/admin/static_src), the resources have to be rebuilt.

This can be done with

python setup.py build_resources

The command also accepts couple arguments, see its help for more details:

python setup.py build_resources --help

Running tests

To run tests in the active virtualenv:

py.test -v shoop_tests
# Or with coverage
py.test -vvv --cov shoop --cov-report html shoop_tests

To run tests for all supported Python versions run:

pip install tox  # To install tox, needed just once
tox

Collecting translatable messages

To update the PO catalog files which contain translatable (and translated) messages, issue shoop_makemessages management command in the shoop directory:

cd shoop && python -m shoop_workbench shoop_makemessages

Docstring coverage

The DocCov script is included for calculating some documentation coverage metrics.

python _misc/doccov.py shoop/core -o doccov.html

Development Tools

Sanity Checker

The check_sanity.py tool does basic text file sanity checking on the codebase.

python _misc/check_sanity.py

DocCov

The doccov.py tool checks for docstring coverage and docstring style.

python _misc/doccov.py -o report.html shoop

Ensure Code Style

The ensure_code_style.py tool has a couple checkers:

  • one that checks that all ForeignKey``s are declared with ``on_delete clauses
  • one that checks that model and form fields have properly translatable verbose names
python _misc/ensure_code_style.py shoop

Ensure License Headers

The ensure_license_headers.py tool checks that all source files have the requisite license header. It can also optionally write the headers to the files by itself.

python _misc/ensure_license_headers.py shoop
# or to write changes:
python _misc/ensure_license_headers.py -w shoop

Ensure Unicode Literals

The ensure_unicode_literals.py tool checks that all Python files have the from __future import unicode_literals statement, to improve Python 2 compatibility.

It can also optionally add these statements itself.

python _misc/ensure_unicode_literals.py shoop
# or to write changes:
python _misc/ensure_unicode_literals.py -w shoop

Data model

Data in Shoop is stored into database using regular Django models and it is accessed with Django’s normal query API. See shoop.core.models for list of models in Shoop Core.

Extending models

Non-polymorphic models

Basic models (like Product, Category or Order) cannot be replaced. To extend them, create a new model for your extensions and link that to the original model with a OneToOneField.

For example:

from django.core import models
from shoop.core import models as shoop_models

class MyProduct(models.Model):
    product = models.OneToOneField(shoop_models.Product)

    # fields of the extension...
    my_field = models.CharField(max_length=10)
    ...

Todo

Check Multi-table inheritance for extending models

Note

Even though basic models cannot be replaced, it is possible to replace the User model. See Specifying a custom User model.

Polymorphic models

Polymorphic models (like Contact) can be extended by inheritance. The polymorphic base class has a model manager that makes sure that the returned objects are correct type. For example, when getting all Contacts with a query like Contact.objects.all(), the returned QuerySet may have instances of PersonContact, CompanyContact and your custom class.

See django-polymorphic’s documentation for details.

The Provides system

The Provides system is Shoop’s mechanism for discovering and loading components, both first-party and third-party. Shoop apps use the provides system in various ways.

  • The core itself uses Provides for discovering method and supplier modules.
  • shoop.admin uses Provides to load admin modules, form customizations etc.
  • shoop.front uses it for URLconf overrides etc.

Todo

Document the various ways better.

Provides are grouped under different categories, such as admin_module, shipping_method_module, front_urls, etc.

Declaring Provides

Shoop uses the Django 1.7+ AppConfig system to declare provides.

Quite simply, a developer needs only include a dict with provide categories as the keys and lists of loading specs as values for new provides to be discovered.

class PigeonAppConfig(AppConfig):

    provides = {
        "shipping_method_module": [
            "pigeon.module:PigeonShippingModule"
        ]
    }

Note

Some provides also require the class named by the spec string to include an identifier field. Refer to the implementation guides for particular functionalities for details.

Using Provides

Provide management functions are found in the shoop.apps.provides module.

In general, the shoop.apps.provides.get_provide_objects method is your most useful entry point.

Provide Categories

admin_category_form_part
Additional FormPart classes for Category editing.
admin_contact_form_part
Additional FormPart classes for Contact editing.
admin_product_form_part
Additional FormPart classes for Product editing. (This is used by pricing modules, for instance.)
admin_module
Admin module classes. Practically all of the functionality in the admin is built via admin modules.
front_template_helper_namespace
Additional namespaces to install in the shoop “package” within template contexts. .. seealso:: Custom Template Helper Functions
front_urls
Lists of frontend URLs to be appended to the usual frontend URLs.
front_urls_post
Lists of frontend URLs to be appended to the usual frontend URLs, even after front_urls. Most of the time, front_urls should do.
front_urls_pre
Lists of frontend URLs to be prepended to the usual frontend URLs. Most of the time, front_urls should do.
notify_action
Notification framework Action classes.
notify_condition
Notification framework Condition classes.
notify_event
Notification framework Event classes.
payment_method_module
Payment method module classes (deriving from shoop.core.methods.base.BasePaymentMethodModule), as used by shoop.core.models.PaymentMethod.
pricing_module
Pricing module classes; the pricing module in use is set with the SHOOP_PRICING_MODULE setting.
shipping_method_module
Shipping method module classes (deriving from shoop.core.methods.base.BaseShippingMethodModule), as used by shoop.core.models.ShippingMethod.
supplier_module
Supplier module classes (deriving from shoop.core.suppliers.base.BaseSupplierModule), as used by shoop.core.models.Supplier.
tax_module
Tax module classes; the tax module in use is set with the SHOOP_TAX_MODULE setting.
xtheme
XTheme themes (full theme sets).
xtheme_plugin
XTheme plugins (that are placed into placeholders within themes).
xtheme_resource_injection
XTheme resources injection function that takes current context and content as parameters.

Addons

Shoop contains facilities for installing, detecting, loading and configuring additional functionality with little or no system administration knowledge needed. Packages that can be loaded in this way are called Addons. Addons aren’t very special, though: under the surface they are nothing more than standard Django applications that are discovered using the Setuptools Entry Points mechanism. Functionality registration after this occurs via the Shoop Provides subsystem.

Configuring your project to load addons

The Shoop addon manager handles adding addons into Django’s INSTALLED_APPS list during project initialization time.

It’s easy to convert a standard Django configuration to be addons enabled.

For instance, take a bare-bones Shoop core installation.

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'shoop.core',
    'shoop.simple_pricing',
    'shoop.simple_supplier',
    'shoop.default_tax',
    'shoop.admin',
)

The management interface for the addon loader requires one additional configuration key, SHOOP_ENABLED_ADDONS_FILE, to name a path to a configuration file that is writable by the application server.

The shoop.addons.add_enabled_addons() method manages reading this file, cross-referencing them with the entry points published by Setuptools and adding them into the installed apps list.

Putting this all together,

from shoop.addons import add_enabled_addons

# *snip*

# This varies depending on how your particular project arranges writable files.
SHOOP_ENABLED_ADDONS_FILE = os.path.join(BASE_DIR, "enabled_addons")

INSTALLED_APPS = add_enabled_addons(SHOOP_ENABLED_ADDONS_FILE, (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'shoop.core',
    'shoop.simple_pricing',
    'shoop.simple_supplier',
    'shoop.default_tax',
    'shoop.admin',
    'shoop.addons',
))

# *snip*

will enable your project to load Shoop addons.

Installing and configuring addons

Once shoop.addons is in your INSTALLED_APPS list, a section for managing addons appears in the administration panel.

Developing addons

As discussed before, addons are simply Django applications with a Setuptools entry_points stanza in setup.py.

This means addon development doesn’t require any special steps; just adding the new application to a test project’s (such as Workbench’s) INSTALLED_APPS is enough to get you running.

Preparing addons for distribution

When the time comes to actually distribute your new addon, configure your package according to the PyPUG guidelines and within the entry_points section add a shoop.addon entry point stanza, such as this (example taken from the shoop-pugme addon):

setuptools.setup(
    # ...
    entry_points={"shoop.addon": "shoop_pugme=shoop_pugme"}
)

Note

It’s recommended you follow the name=name format for the entry point definition. Further iterations of addon discovery may change the format.

With this in your setup.py, you can now

  • Use python setup.py sdist to create a source distribution for your addon and install it via the administration panel as you would for any old addon.
  • Or run pip install -e . to install the addon in your shop’s virtualenv in editable mode, then enable the addon via the administration panel.

(If you had manually added the application into your INSTALLED_APPS as discussed before, this would be a good time to take it out of there, as otherwise Django will complain about duplicates.)

Implementation of Prices and Taxes in Shoop

This document describes deeper details about price and tax implementation in Shoop from a developer’s point of view. To understand the basics, please read Prices and Taxes in Shoop first.

Types Used for Prices and Taxes

Money

Used to represent money amounts (that are not prices). It is basically a Decimal number with a currency.

Price

Used to represent prices. Price is a Money with an includes_tax property. It has has two subclasses: TaxfulPrice and TaxlessPrice.

There should usually be no need to create prices directly with these classes; see Creating Prices.

Priceful

An interface for accessing the price information of a product, order line, basket line, or whatever. See Accessing Prices of Product or Line.

PriceInfo

A class for describing an item’s price information.

PricingModule

An interface for querying prices of products.

PricingContext

A container for variables that affect pricing. Pricing modules may subclass this.

PricingContextable

An interface for objects that can be converted to a pricing context. Instances of PricingContext or HttpRequest satisfy this interface.

LineTax

An interface for describing a calculated tax of a line in order or basket. Has a reference to the line and to the applied tax and the calculated amount of tax. One line could have several taxes applied, each is presented with a separate LineTax.

SourceLineTax

A container for a calculated tax of a SourceLine (or BasketLine). Implements the LineTax interface.

OrderLineTax

A Django model for persistently storing the calculated tax of an OrderLine. Implements the LineTax interface.

Tax

A Django model for a tax with name, code, and percentage rate or fixed amount. Fixed amounts are not yet supported.

Todo

Fix this when fixed amounts are supported.

TaxableItem

An interface for items that can be taxed. Implemented by Product, ShippingMethod, PaymentMethod and SourceLine.

TaxClass

A Django model for a tax class. Taxable items (e.g. products, methods or lines) are grouped to tax classes to make it possible to have different taxation rules for different groups of items.

CustomerTaxGroup

A Django model for grouping customers to make it possible to have different taxation rules for different groups of customers. Shoop assigns separate CustomerTaxGroup`s for a `~shoop.core.models.PersonContact and a CompanyContact by default.

TaxModule

An interface for calculating the taxes of an OrderSource or any TaxableItem. The Shoop Base distribution ships a concrete implementation of a TaxModule called DefaultTaxModule. It is a based on a table of tax rules (saved with TaxRule model). See The Default Tax Module. Used TaxModule can be changed with SHOOP_TAX_MODULE setting.

TaxedPrice

A type to represent the return value of tax calculation. Contains a pair of prices, TaxfulPrice and TaxlessPrice, of which one is the original price before the calculation and the other is the calculated price. Also contains a list of the applied taxes. TaxedPrice is the return type of get_taxed_price_for method in the TaxModule interface.

TaxingContext

A container for variables that affect taxing, such as customer tax group, customer tax number, location (country, postal code, etc.). Used in the TaxModule interface. Note: This is not usually subclassed.

Creating Prices

When implementing a PricingModule or another module that has to create prices, use the Shop.create_price method. It makes sure that all prices have the same price unit.

Accessing Prices of Product or Line

There is a Priceful interface for accessing prices. It is implemented by OrderLine and SourceLine, BasketLine, and PriceInfo which is returned e.g. by get_price_info method.

Notification Framework

The purpose of the notification framework is to be a generic, run-time configurable and code extensible system to inform interested parties about events in the store.

Events could include

  • orders being created
  • shipments being dispatched
  • orders being canceled
  • products reaching a given stock threshold
  • a user requesting a password reset

et cetera.

Notifications may be delivered over different channels, such as email, SMS, phone or even instant messages, as delivery channels are also pluggable.

It is known that the notification framework partially overlaps the Django signal system as used in Shoop in scope. However Django signals are not user-configurable and their purpose is different.

Glossary

  • Event - a class of notifiable event
  • Event Variables - a set of typed variables pertaining to a given event
  • Script - a configurable object describing the chain of system actions in response to an Event
  • Script Context - a set of variables populated from the event variables before the script is begun
  • Action - a configured action within a script, such as “Send email to x@y.local
  • Action Class - a type of action provided by an app (or built-in to the notification framework), such as “Send Email”
  • Condition - a configured conditional enabling actions within a script, such as “If Order Contains Product XYZ-1”
  • Condition Class - a type of condition provided by an app (or built-in to the notification framework), such as “If Order Contains Product”
  • Template - a possibly multilingual set of textual templates attached to Actions that require configurable text.
  • Attachment - a named, MIME-typed assumedly binary blob that may be delivered along a notification, such as a PDF order confirmation.

Events

An Event represents a single event that may occur in the system.

Events are registered through the Shoop Apps’ provides mechanism and must have unique identifiers (“event identifier”).

Events provide typed variables that may be utilized in script items, in either variable bindings or message templates.

In addition, a number of system variables are made available for all events.

For instance, an “Order Created” event could provide the variables

  • order (type Order) - the order itself
  • customer_email (type email) - the customer’s email address (extracted from the order)
  • customer_phone (type phone) - the customer’s phone number (extracted from the order)
  • payment_email (type email) - the payment email address (extracted from the order)
  • shipment_email (type email) - the shipment email address (extracted from the order)
  • language (type language) - the customer’s preferred language (extracted from the order)

and a default script that sends a pre-defined text template to the customer email.

A “Password Reset” event could provide the variables

  • user (type User) - the requesting user
  • user_email (type email) - the email address of the user
  • password_reset_url (type URL) - the URL for resetting the password.

Scripts

Event scripts define the rules, i.e. conditions and actions defining what to do when a notification event occurs. A single event may have multiple scripts attached; all of them are executed if they are enabled.

A script may be as simple as “Always -> Send Email -> Stop”, or it may have conditions that send emails with different templates depending on the language of the order, or products contained within the order.

Events may provide a script template, which can be loaded for further configuration by the shop administrator. No scripts are loaded by default, though. If no scripts exist for an event, nothing is done when the event occurs.

The model for scripts is a “routing table” with steps of the form “Conditions / Actions / Next”. This is somewhat modeled after uWSGI’s Internal Routing system. Note: This would be easy to upgrade to a full-fledged flowchart/data-flow programming environment akin to Unreal Engine 4’s Blueprint Visual Scripting system.

The Conditions set for a script step may be joined with different conditional operators. Currently, “All”, “Any” and “None” are implemented. The actions for a single step are executed sequentially.

The actions for “Next” are “Continue” and “Stop”. (A “Goto” action is also possible, but it is not considered a requirement at present.) “Continue” will continue executing the routing table from the next step, and “Stop” will cease script execution.

The Condition and Action classes available for notification scripts are also provided via the provides mechanism; many actions are built-in (provided by the notification framework itself), but may be extended by other apps. Like Events, Condition classes and Action classes have unique identifiers.

Conditions and Actions are configurable. The configurable variables are set by the Condition classes and Action classes, using the same typology as Event variables.

For instance, Conditional classes could include

  • “Language Equals” (configured by a variable of type Language and a constant of type Language)
  • “Order Contains Product SKU” (configured by a variable of type Order and a constant of type String)
  • “Order Is Paid” (configured by a variable of type Order)

and Action classes might include

  • “Send Plain-Text Email” (configured by variable/constant of type Email and a template (see below))
  • “Send Text and HTML Email”

Extension Action classes for, say, integration might even contain

  • “Send Order To External System XYZ”

The recipients, etc. for emails are configurable, making it possible to easily implement merchant order notifications using the same Actions and Conditions.

Templates

Most, if not all, actions require some sort of templating. The Jinja2 language is used for the templates. Templates may contain multiple sections, such as “Subject” or “Content”; these are set by the Action requesting an editable template, as the template editor is embedded in the Action’s configuration view.

An action may request multilingual templates. Multilingual templates duplicate each section for all languages set in the system configuration. (The sending Action is naturally then expected to be configurable by a variable or constant of type Language.)

Attachments

Many actions may also require attachments and other data such as PDF order confirmations, product manuals, etc. that may or may not be generated during dispatch.

To solve this, the script context also includes a list of Attachment objects (details TBD).

Actions such as “Render Order Confirmation PDF” would add Attachment objects to the context, while sending actions would consume them (optionally without removing them) from the context.

Notification Dispatch

Depending on the deployment and implementation, notification dispatch may occur asynchronously (in a non-blocking manner).

The author currently foresees no use case where asynchronous dispatch would cause issues, and as such, the specification contains no mechanism for declaring an event or script to be forcibly synchronous.

Persistent Notifications

In addition to the script core, the Notify app provides a Django model for notifications stored in the shop’s database. These are currently used only in the admin backend, but could be used in the frontend as well.

Template Design

This part of the documentation covers the structural elements of Shoop’s default templates and instructs you on how to create your own customized templates.

To be able to create customized templates you’ll need to have understanding of the principles of HTML and CSS.

If you would like to start creating your own customized templates with these instructions you should already have a working Shoop installation with the default frontend theme up and running. If not, you can start by reading Getting Started guide.

Shoop’s default frontend theme

Shoop’s frontend templates are written with Jinja2 which is a templating engine for Python very similar to Django’s templates.

The default frontend theme uses the Bootstrap 3 framework, which consists of Bootstrap’s HTML structure and Bootstrap specified CSS classes. If you want to create your own templates, it would require using Bootstrap 3 or overwriting all the template files with your custom HTML structure and HTML classes.

Shoop’s template files are easy to modify and basic knowledge of HTML and CSS takes you far. Shoop’s frontend and the default theme already include the necessary template tags to print out all the features a basic shop would need. It is fairly simple to add your custom HTML elements around template tags and customize your shop to your needs.

Template folder structure

Shoop utilizes a similar folder structure for all the templates in different apps. All the template files are always included in the app folder shoop/APP/templates/.

Within this template folder the folder structure is: APP/MODULE/TEMPLATE.jinja. For example, this could be converted into shoop/product/detail.jinja

The default frontend theme can be found in shoop/front/apps/default_theme/.

Example

The Simple CMS module has a template to show pages created with it. This page.jinja template can be found under the Simple CMS template folder: shoop/simple_cms/templates/ where the path to the template file is shoop/simple_cms/page.jinja.

Other default features such as user authentication, customer info, order history, registration and search etc. can be found in their own application templates under shoop/front/apps/. Each app has it’s own template folder containing application specific templates.

Templates have been split into separate files and each file has its own purpose. Template files inherit the base layout from shoop/base.jinja.

General

General template files can be found under shoop/front/templates/

Base shoop/front/base.jinja
Defines the structure of your templates. It includes the <html>, <head> and <body> tags, and the general structure of all frontend pages (unless explicitly overridden).
Index shoop/front/index.jinja
Your shop’s home page.
Macros shoop/front/macros.jinja
Additional template macros that can be used in other template files. For example single product box is rendered with a macro, where it can be called with customized parameters. Also form fields, alerts and order details can be generated with macros.
Includes shoop/front/includes/
Additional HTML that can be included in pages. In the default frontend theme all the included filenames start with _. All navigation related HTML and template tags are included to base.jinja and for example you could create a _footer.jinja to be included if needed.
Products and Categories

Product and category templates can be found under shoop/front/templates/

Detail shoop/front/product/detail.jinja
The view for a single product. Displays a product and its details. The file uses template tags to include product attributes and ordering sections.
Category shoop/front/product/category.jinja
A view for a single category. This template lists all the products of the selected category.
Shopping basket

All shopping basket related templates go in the shoop/front/templates/shoop/front/basket folder. This includes the default structure of the shopping basket and additional shopping basket elements.

The default shopping basket template also includes the ordering form. This does not apply to shops using multi-phase checkout.

Default Basket shoop/front/basket/default_basket.jinja
The structure of shopping basket. It includes the shopping basket’s contents as a table from a separate file in the partials folder. The ordering form is also displayed in this file.
Orders

Order related templates can be found in shoop/front/templates/shoop/front/order/.

Complete shoop/front/order/complete.jinja
Displays the order success message and details of the order.
Payment Canceled shoop/front/order/payment_canceled.jinja
Template for displaying payment cancellation.
Authentication

Authentication through the Shoop Front is another sub-app. Its templates can be found in its own folder: shoop/front/apps/auth/templates/shoop/user/

Login and Logout
Templates for login form and logout message pages.
Password Recovery
Password recovery process including the templates for shop and e-mail.
Registration

Registration is another sub-app. Its templates can be found in: shoop/front/apps/registration/templates

Registration Form shoop/registration/register.jinja
Registration form template for new users.
Activation Failed shoop/registration/activation_failed.jinja
A template for displaying an error message when account activation fails.
Customer Information

Customer information is another sub-app. Its templates can be found in: shoop/front/apps/customer_information/templates/

Edit shoop/customer_information/edit.jinja
Template for editing customer details.
Personal Order History

Personal Order History, another sub-app, naturally has its templates in its own folder. shoop/front/apps/personal_order_history/templates/

Order Detail shoop/personal_order_history/order_detail.jinja
Template for displaying single order’s details.
Order List shoop/personal_order_history/order_list.jinja
Template for listing all the previous personal orders.

Custom Template Helper Functions

This paragraph explains how to register template functions in Shoop’s sub-apps. If you are interested in Jinja2‘s way to do it, please refer to the Jinja2 documentation.

The AppConfig

The front_template_helper_namespace category in the provides dictionary tells the framework that there are template helper functions to be found in the namespace class (TemplateHelper) given.

For more information about provides please refer to the documentation

The TemplateHelper class

This class contains all the functions that the are exposed for frontend templates.

Using helpers in a template

The template helpers can be used in templates with shoop.<module_name>.<TemplateHelper::method>(). For example shoop.my_module.get_day_names().

Static files

Static files such as images, stylesheets and scripts go under the static folder, using the Django staticfiles framework.

You can access static data files in templates by using the {{ static() }} function. For example, if you have img/image.jpg in your static files, generating a src for an <img> tag would be as easy as <img src="{{ static(img/image.jpg") }}">.

Creating custom templates

You may either derive your own theme from the default theme, or write your own from scratch.

The basic principle of deriving custom Shoop templates is not to modify the original files (default frontend themes) within the app directory, but to copy them into to your own application’s template directory. If your own application is listed before shoop.front (and/or other theme apps) in Django’s INSTALLED_APPS configuration, Django will prefer your templates over others with the same path.

This means it is possible to overwrite only some of the default files or all of them. If there is no customized template with the same path and filename, Django will use the default file instead.

All the template files that you want to customize go under your application’s template folder in the same folder hierarchy as under the original app’s templates folder. The folder hierarchy for frontend templates was discussed earlier in this document.

Example

Let’s say you only would like to make a customized home page for your shop, but leave all other templates as they are. Let’s call your application myshop.

Simply copy index.jinja from shoop/front/templates/shoop/index.jinja to your application’s template folder myshop/templates/shoop/index.jinja, then modify it to your heart’s content.

Now let’s say you want to tweak the product category view too.

Copy shoop/front/templates/shoop/product/category.jinja to myshop/templates/shoop/product/category.jinja, then start modifying. As you can see, the template directory structure within your myshop application reflects the one in the original app.

Shoop API Documentation

Shoop Application API

See shoop.apps.

Shoop Packages and Modules

shoop package
Subpackages
shoop.addons package
Subpackages
shoop.addons.admin_module package
Subpackages
shoop.addons.admin_module.views package
Submodules
shoop.addons.admin_module.views.list module
class shoop.addons.admin_module.views.list.AddonEnableDisableForm(**kwargs)[source]

Bases: django.forms.forms.Form

get_enabled_addons()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.addons.admin_module.views.list.AddonListView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/addons/list.jinja'
form_class

alias of AddonEnableDisableForm

form_valid(form)[source]
get_context_data(**kwargs)[source]
shoop.addons.admin_module.views.reload module
class shoop.addons.admin_module.views.reload.ReloadMethodForm(**kwargs)[source]

Bases: django.forms.forms.Form

get_viable_reload_methods()[source]
get_selected_reload_method()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.addons.admin_module.views.reload.ReloadView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/addons/reload.jinja'
form_class

alias of ReloadMethodForm

form_valid(form)[source]
get(request, *args, **kwargs)[source]
shoop.addons.admin_module.views.upload module
class shoop.addons.admin_module.views.upload.AddonUploadForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

base_fields = OrderedDict([('file', <django.forms.fields.FileField object at 0x7f655b872240>)])
declared_fields = OrderedDict([('file', <django.forms.fields.FileField object at 0x7f655b872240>)])
media
class shoop.addons.admin_module.views.upload.AddonUploadView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of AddonUploadForm

template_name = 'shoop/admin/addons/upload.jinja'
title = 'Upload Addon'
form_valid(form)[source]
get_context_data(**kwargs)[source]
class shoop.addons.admin_module.views.upload.AddonUploadConfirmView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of Form

template_name = 'shoop/admin/addons/upload_confirm.jinja'
title = 'Upload Addon'
get_addon_path()[source]
get_context_data(**kwargs)[source]
form_valid(form)[source]
Module contents
class shoop.addons.admin_module.views.AddonListView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of AddonEnableDisableForm

form_valid(form)[source]
get_context_data(**kwargs)[source]
template_name = 'shoop/admin/addons/list.jinja'
class shoop.addons.admin_module.views.AddonUploadView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of AddonUploadForm

form_valid(form)[source]
get_context_data(**kwargs)[source]
template_name = 'shoop/admin/addons/upload.jinja'
title = 'Upload Addon'
class shoop.addons.admin_module.views.AddonUploadConfirmView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of Form

form_valid(form)[source]
get_addon_path()[source]
get_context_data(**kwargs)[source]
template_name = 'shoop/admin/addons/upload_confirm.jinja'
title = 'Upload Addon'
class shoop.addons.admin_module.views.ReloadView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of ReloadMethodForm

form_valid(form)[source]
get(request, *args, **kwargs)[source]
template_name = 'shoop/admin/addons/reload.jinja'
Module contents
class shoop.addons.admin_module.AddonModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
Submodules
shoop.addons.installer module
shoop.addons.installer.get_pip_path()[source]

Try to figure out an explicit path to the Pip executable script.

Returns:Pip path
Return type:str
class shoop.addons.installer.PackageInstaller[source]

Bases: object

install_package(package_path)[source]
get_log()[source]
shoop.addons.manager module
shoop.addons.manager.get_addons_from_entry_points()[source]
shoop.addons.manager.get_enabled_addons(file_path)[source]
shoop.addons.manager.set_enabled_addons(file_path, addons, comment=None)[source]
shoop.addons.manager.add_enabled_addons(addon_filename, apps)[source]
shoop.addons.reloader module
class shoop.addons.reloader.ReloadMethod[source]

Bases: object

identifier = None
title = None
execute()[source]
is_viable()[source]
class shoop.addons.reloader.UwsgiReloadMethod[source]

Bases: shoop.addons.reloader.ReloadMethod

identifier = 'uwsgi'
title = 'Reload uWSGI (uwsgi.reload())'
is_viable()[source]
execute()[source]
class shoop.addons.reloader.DevServerReloadMethod[source]

Bases: shoop.addons.reloader.ReloadMethod

identifier = 'devserver'
title = 'Reload Django Dev Server'
is_viable()[source]
execute()[source]
class shoop.addons.reloader.ModWSGIReloadMethod[source]

Bases: shoop.addons.reloader.ReloadMethod

identifier = 'mod_wsgi'
title = 'Reload Daemon Mode mod_wsgi'
is_viable()[source]
execute()[source]
class shoop.addons.reloader.GunicornReloadMethod[source]

Bases: shoop.addons.reloader.ReloadMethod

identifier = 'gunicorn'
title = 'Reload Gunicorn Master'
is_parent_an_unicorn()[source]
is_viable()[source]
execute()[source]
shoop.addons.reloader.get_reload_method_classes()[source]
Module contents
shoop.addons.add_enabled_addons(addon_filename, apps)[source]
shoop.admin package
Subpackages
shoop.admin.dashboard package
Submodules
shoop.admin.dashboard.blocks module
class shoop.admin.dashboard.blocks.DashboardBlock(id, size=None, color=None)[source]

Bases: object

type = None
SIZES = ('small', 'medium', 'large', 'full')
default_size = 'normal'
class shoop.admin.dashboard.blocks.DashboardContentBlock(id, content, size='normal')[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

type = 'normal'
classmethod by_rendering_template(id, request, template_name, context)[source]
class shoop.admin.dashboard.blocks.DashboardValueBlock(id, value, title, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

type = 'value'
default_size = 'small'
class shoop.admin.dashboard.blocks.DashboardNumberBlock(id, value, title, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardValueBlock

class shoop.admin.dashboard.blocks.DashboardMoneyBlock(id, value, title, currency, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardValueBlock

class shoop.admin.dashboard.blocks.DashboardChartBlock(id, size='normal')[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

type = 'chart'
default_size = 'medium'
BLOCK_TEMPLATE = '\n <h2 class="block-title"><i class="fa fa-bar-chart"></i>%(title)s</h2>\n <div id="chart-%(id)s"></div>\n <script>\n window.CHART_CONFIGS = window.CHART_CONFIGS || {};\n window.CHART_CONFIGS["%(id)s"] = %(config)s;\n </script>\n '
get_chart()[source]

Get the actual chart instance for this block.

Returns:The chart (or None, if it can’t be rendered)
Return type:shoop.admin.dashboard.charts.Chart|None
shoop.admin.dashboard.charts module
class shoop.admin.dashboard.charts.Chart(title)[source]

Bases: object

get_config()[source]

Get a JSONable dictionary of configuration data for this chart. This is passed on as CHART_CONFIGS in the JS environment and eventually processed by dashboard-charts.js.

Returns:Dict of configuration
Return type:dict
get_config_json()[source]
class shoop.admin.dashboard.charts.BarChart(title, labels)[source]

Bases: shoop.admin.dashboard.charts.Chart

add_data(name, data)[source]
get_config()[source]
shoop.admin.dashboard.utils module
shoop.admin.dashboard.utils.get_activity(request, n_entries=30, cutoff_hours=10)[source]

Get Activity objects from all modules as a list in latest-first order.

Parameters:
  • request (django.http.request.HttpRequest) – Request context
  • n_entries (int) – Number of entries to return in total.
  • cutoff_hours (float) – Calculate cutoff datetime so the oldest entry should be at most this old
Returns:

List of Activity objects

Return type:

list[Activity]

Module contents
class shoop.admin.dashboard.BarChart(title, labels)[source]

Bases: shoop.admin.dashboard.charts.Chart

add_data(name, data)[source]
get_config()[source]
class shoop.admin.dashboard.DashboardBlock(id, size=None, color=None)[source]

Bases: object

SIZES = ('small', 'medium', 'large', 'full')
default_size = 'normal'
type = None
class shoop.admin.dashboard.DashboardChartBlock(id, size='normal')[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

BLOCK_TEMPLATE = '\n <h2 class="block-title"><i class="fa fa-bar-chart"></i>%(title)s</h2>\n <div id="chart-%(id)s"></div>\n <script>\n window.CHART_CONFIGS = window.CHART_CONFIGS || {};\n window.CHART_CONFIGS["%(id)s"] = %(config)s;\n </script>\n '
default_size = 'medium'
get_chart()[source]

Get the actual chart instance for this block.

Returns:The chart (or None, if it can’t be rendered)
Return type:shoop.admin.dashboard.charts.Chart|None
type = 'chart'
class shoop.admin.dashboard.DashboardContentBlock(id, content, size='normal')[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

classmethod by_rendering_template(id, request, template_name, context)[source]
type = 'normal'
class shoop.admin.dashboard.DashboardMoneyBlock(id, value, title, currency, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardValueBlock

class shoop.admin.dashboard.DashboardNumberBlock(id, value, title, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardValueBlock

class shoop.admin.dashboard.DashboardValueBlock(id, value, title, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardBlock

default_size = 'small'
type = 'value'
shoop.admin.dashboard.get_activity(request, n_entries=30, cutoff_hours=10)[source]

Get Activity objects from all modules as a list in latest-first order.

Parameters:
  • request (django.http.request.HttpRequest) – Request context
  • n_entries (int) – Number of entries to return in total.
  • cutoff_hours (float) – Calculate cutoff datetime so the oldest entry should be at most this old
Returns:

List of Activity objects

Return type:

list[Activity]

shoop.admin.forms package
Submodules
shoop.admin.forms.fields module
class shoop.admin.forms.fields.PercentageField(max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs)[source]

Bases: django.forms.fields.DecimalField

MULTIPLIER = Decimal('100')
prepare_value(value)[source]
to_python(value)[source]
widget_attrs(widget)[source]
shoop.admin.forms.widgets module
class shoop.admin.forms.widgets.BasePopupChoiceWidget(attrs=None, clearable=False, empty_text='—')[source]

Bases: django.forms.widgets.Widget

browse_kind = None
filter = None
get_browse_markup()[source]
get_clear_markup()[source]
render_text(obj)[source]
get_object(value)[source]
render(name, value, attrs=None)[source]
media
class shoop.admin.forms.widgets.MediaChoiceWidget(attrs=None, clearable=False, empty_text='—')[source]

Bases: shoop.admin.forms.widgets.BasePopupChoiceWidget

browse_kind = 'media'
get_object(value)[source]
media
class shoop.admin.forms.widgets.ImageChoiceWidget(attrs=None, clearable=False, empty_text='—')[source]

Bases: shoop.admin.forms.widgets.MediaChoiceWidget

filter = 'images'
media
class shoop.admin.forms.widgets.ProductChoiceWidget(attrs=None, clearable=False, empty_text='—')[source]

Bases: shoop.admin.forms.widgets.BasePopupChoiceWidget

browse_kind = 'product'
get_object(value)[source]
media
Module contents
shoop.admin.modules package
Subpackages
shoop.admin.modules.attributes package
Subpackages
shoop.admin.modules.attributes.views package
Submodules
shoop.admin.modules.attributes.views.edit module
class shoop.admin.modules.attributes.views.edit.AttributeForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of Attribute

exclude = ()
AttributeForm.base_fields = OrderedDict([('identifier', <django.forms.fields.CharField object at 0x7f655aa8b4a8>), ('searchable', <django.forms.fields.BooleanField object at 0x7f655aa8b278>), ('type', <enumfields.forms.EnumChoiceField object at 0x7f655aa8b7f0>), ('visibility_mode', <enumfields.forms.EnumChoiceField object at 0x7f655aa8bb70>), ('name', <django.forms.fields.CharField object at 0x7f655a9e85f8>)])
AttributeForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a9e85f8>)])
AttributeForm.media
class shoop.admin.modules.attributes.views.edit.AttributeEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Attribute

form_class

alias of AttributeForm

template_name = 'shoop/admin/attributes/edit.jinja'
context_object_name = 'attribute'
shoop.admin.modules.attributes.views.list module
class shoop.admin.modules.attributes.views.list.AttributeListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Attribute

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655aa1da90>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8390>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8748>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e87f0>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8860>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e88d0>]
get_queryset()[source]
Module contents
class shoop.admin.modules.attributes.views.AttributeEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'attribute'
form_class

alias of AttributeForm

model

alias of Attribute

template_name = 'shoop/admin/attributes/edit.jinja'
class shoop.admin.modules.attributes.views.AttributeListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655aa1da90>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8390>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8748>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e87f0>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e8860>, <shoop.admin.utils.picotable.Column object at 0x7f655a9e88d0>]
get_queryset()[source]
model

alias of Attribute

Module contents
class shoop.admin.modules.attributes.AttributeModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.categories package
Subpackages
shoop.admin.modules.categories.views package
Submodules
shoop.admin.modules.categories.views.edit module
class shoop.admin.modules.categories.views.edit.CategoryBaseForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of Category

fields = ('parent', 'shops', 'status', 'ordering', 'visibility', 'visibility_groups', 'name', 'image', 'description', 'slug')
widgets = {'visibility': <class 'django.forms.widgets.RadioSelect'>, 'status': <class 'django.forms.widgets.RadioSelect'>}
CategoryBaseForm.base_fields = OrderedDict([('parent', <mptt.forms.TreeNodeChoiceField object at 0x7f655b15ca20>), ('shops', <django.forms.models.ModelMultipleChoiceField object at 0x7f655b15cef0>), ('status', <enumfields.forms.EnumChoiceField object at 0x7f655b15c588>), ('ordering', <django.forms.fields.IntegerField object at 0x7f655b173c50>), ('visibility', <enumfields.forms.EnumChoiceField object at 0x7f655b173128>), ('visibility_groups', <django.forms.models.ModelMultipleChoiceField object at 0x7f655b173748>), ('name', <django.forms.fields.CharField object at 0x7f655b151a58>), ('image', <filer.fields.image.AdminImageFormField object at 0x7f655b15c940>), ('description', <django.forms.fields.CharField object at 0x7f655b15c6a0>), ('slug', <django.forms.fields.SlugField object at 0x7f655b15c390>)])
CategoryBaseForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655b151a58>), ('description', <django.forms.fields.CharField object at 0x7f655b15c6a0>), ('slug', <django.forms.fields.SlugField object at 0x7f655b15c390>)])
CategoryBaseForm.media
class shoop.admin.modules.categories.views.edit.CategoryBaseFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -1000
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.categories.views.edit.CategoryEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Category

template_name = 'shoop/admin/categories/edit.jinja'
context_object_name = 'category'
base_form_part_classes = [<class 'shoop.admin.modules.categories.views.edit.CategoryBaseFormPart'>]
form_part_class_provide_key = 'admin_category_form_part'
form_valid(form)[source]
shoop.admin.modules.categories.views.list module
class shoop.admin.modules.categories.views.list.CategoryListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Category

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b16a550>, <shoop.admin.utils.picotable.Column object at 0x7f655aa7afd0>, <shoop.admin.utils.picotable.Column object at 0x7f655aa86320>, <shoop.admin.utils.picotable.Column object at 0x7f655b1733c8>]
get_queryset()[source]
get_object_abstract(instance, item)[source]
Module contents
class shoop.admin.modules.categories.views.CategoryEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

base_form_part_classes = [<class 'shoop.admin.modules.categories.views.edit.CategoryBaseFormPart'>]
context_object_name = 'category'
form_part_class_provide_key = 'admin_category_form_part'
form_valid(form)[source]
model

alias of Category

template_name = 'shoop/admin/categories/edit.jinja'
class shoop.admin.modules.categories.views.CategoryListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b16a550>, <shoop.admin.utils.picotable.Column object at 0x7f655aa7afd0>, <shoop.admin.utils.picotable.Column object at 0x7f655aa86320>, <shoop.admin.utils.picotable.Column object at 0x7f655b1733c8>]
get_object_abstract(instance, item)[source]
get_queryset()[source]
model

alias of Category

Module contents
class shoop.admin.modules.categories.CategoryModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.contact_groups package
Subpackages
shoop.admin.modules.contact_groups.views package
Submodules
shoop.admin.modules.contact_groups.views.edit module
class shoop.admin.modules.contact_groups.views.edit.ContactGroupForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of ContactGroup

fields = ('name',)
ContactGroupForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655b639a90>)])
ContactGroupForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655b639a90>)])
ContactGroupForm.media
class shoop.admin.modules.contact_groups.views.edit.ContactGroupEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ContactGroup

form_class

alias of ContactGroupForm

template_name = 'shoop/admin/contact_groups/edit.jinja'
context_object_name = 'contact_group'
shoop.admin.modules.contact_groups.views.list module
class shoop.admin.modules.contact_groups.views.list.ContactGroupListView(**kwargs)[source]

Bases: shoop.admin.utils.picotable.PicotableViewMixin, django.views.generic.list.ListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ContactGroup

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655ba3b1d0>, <shoop.admin.utils.picotable.Column object at 0x7f655b8639e8>]
get_queryset()[source]
get_context_data(**kwargs)[source]
Module contents
class shoop.admin.modules.contact_groups.views.ContactGroupEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'contact_group'
form_class

alias of ContactGroupForm

model

alias of ContactGroup

template_name = 'shoop/admin/contact_groups/edit.jinja'
class shoop.admin.modules.contact_groups.views.ContactGroupListView(**kwargs)[source]

Bases: shoop.admin.utils.picotable.PicotableViewMixin, django.views.generic.list.ListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655ba3b1d0>, <shoop.admin.utils.picotable.Column object at 0x7f655b8639e8>]
get_context_data(**kwargs)[source]
get_queryset()[source]
model

alias of ContactGroup

Module contents
class shoop.admin.modules.contact_groups.ContactGroupModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.contacts package
Subpackages
shoop.admin.modules.contacts.views package
Submodules
shoop.admin.modules.contacts.views.detail module
class shoop.admin.modules.contacts.views.detail.ContactDetailToolbar(contact)[source]

Bases: shoop.admin.toolbar.Toolbar

build_renew_password_button()[source]
build_new_user_button()[source]
build()[source]
class shoop.admin.modules.contacts.views.detail.ContactDetailView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Contact

template_name = 'shoop/admin/contacts/detail.jinja'
context_object_name = 'contact'
get_context_data(**kwargs)[source]
shoop.admin.modules.contacts.views.edit module
class shoop.admin.modules.contacts.views.edit.ContactBaseForm(bind_user=None, *args, **kwargs)[source]

Bases: django.forms.models.BaseModelForm

This form is notoriously confusing in that it works in several different modes depending on what the instance being passed in is.

If the instance is an unsaved object, the form will show fields for the common superclass Contact as well as a type selection field. When saving the object, a _new_ instance is created, as its class will have been specialized into the actual concrete polymorphic type. (I said this is confusing.)

If the instance is a saved object, its type is checked and only the related fields are shown and none of that specialization stuff occurs.

FIELDS_BY_MODEL_NAME = {'PersonContact': ('gender', 'birth_date'), 'CompanyContact': ('tax_number',), 'Contact': ('is_active', 'language', 'marketing_permission', 'phone', 'www', 'timezone', 'prefix', 'name', 'suffix', 'name_ext', 'email', 'tax_group')}
generate_fields()[source]
set_model_from_cleaned_data()[source]
save(commit=True)[source]
class shoop.admin.modules.contacts.views.edit.ContactBaseFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -1000
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.contacts.views.edit.AddressForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of MutableAddress

fields = ('prefix', 'name', 'suffix', 'name_ext', 'phone', 'email', 'street', 'street2', 'street3', 'postal_code', 'city', 'region_code', 'region', 'country')
AddressForm.base_fields = OrderedDict([('prefix', <django.forms.fields.CharField object at 0x7f655b47c898>), ('name', <django.forms.fields.CharField object at 0x7f655b47c588>), ('suffix', <django.forms.fields.CharField object at 0x7f655b47c048>), ('name_ext', <django.forms.fields.CharField object at 0x7f655b47c6d8>), ('phone', <django.forms.fields.CharField object at 0x7f655b49af28>), ('email', <django.forms.fields.EmailField object at 0x7f655b49a940>), ('street', <django.forms.fields.CharField object at 0x7f655b49aeb8>), ('street2', <django.forms.fields.CharField object at 0x7f655b49aef0>), ('street3', <django.forms.fields.CharField object at 0x7f655b49a0f0>), ('postal_code', <django.forms.fields.CharField object at 0x7f655b49ac88>), ('city', <django.forms.fields.CharField object at 0x7f655b49ad30>), ('region_code', <django.forms.fields.CharField object at 0x7f655b49a7b8>), ('region', <django.forms.fields.CharField object at 0x7f655b4684e0>), ('country', <django_countries.fields.LazyTypedChoiceField object at 0x7f655b468e10>)])
AddressForm.declared_fields = OrderedDict()
AddressForm.media
class shoop.admin.modules.contacts.views.edit.ContactAddressesFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -900
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.contacts.views.edit.ContactEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Contact

template_name = 'shoop/admin/contacts/edit.jinja'
context_object_name = 'contact'
base_form_part_classes = [<class 'shoop.admin.modules.contacts.views.edit.ContactBaseFormPart'>, <class 'shoop.admin.modules.contacts.views.edit.ContactAddressesFormPart'>]
form_part_class_provide_key = 'admin_contact_form_part'
form_valid(form)[source]
get_toolbar()[source]
shoop.admin.modules.contacts.views.list module
class shoop.admin.modules.contacts.views.list.ContactListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Contact

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b468fd0>, <shoop.admin.utils.picotable.Column object at 0x7f655b468be0>, <shoop.admin.utils.picotable.Column object at 0x7f655b468dd8>, <shoop.admin.utils.picotable.Column object at 0x7f655b468c18>, <shoop.admin.utils.picotable.Column object at 0x7f655b468a58>, <shoop.admin.utils.picotable.Column object at 0x7f655b468518>]
get_queryset()[source]
get_type_display(instance)[source]
get_object_abstract(instance, item)[source]
shoop.admin.modules.contacts.views.reset module
class shoop.admin.modules.contacts.views.reset.ContactResetPasswordView(**kwargs)[source]

Bases: shoop.admin.modules.users.views.password.UserResetPasswordView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_contact()[source]
get_object(queryset=None)[source]
get_success_url()[source]
Module contents
class shoop.admin.modules.contacts.views.ContactListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b468fd0>, <shoop.admin.utils.picotable.Column object at 0x7f655b468be0>, <shoop.admin.utils.picotable.Column object at 0x7f655b468dd8>, <shoop.admin.utils.picotable.Column object at 0x7f655b468c18>, <shoop.admin.utils.picotable.Column object at 0x7f655b468a58>, <shoop.admin.utils.picotable.Column object at 0x7f655b468518>]
get_object_abstract(instance, item)[source]
get_queryset()[source]
get_type_display(instance)[source]
model

alias of Contact

class shoop.admin.modules.contacts.views.ContactDetailView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'contact'
get_context_data(**kwargs)[source]
model

alias of Contact

template_name = 'shoop/admin/contacts/detail.jinja'
class shoop.admin.modules.contacts.views.ContactResetPasswordView(**kwargs)[source]

Bases: shoop.admin.modules.users.views.password.UserResetPasswordView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_contact()[source]
get_object(queryset=None)[source]
get_success_url()[source]
class shoop.admin.modules.contacts.views.ContactEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

base_form_part_classes = [<class 'shoop.admin.modules.contacts.views.edit.ContactBaseFormPart'>, <class 'shoop.admin.modules.contacts.views.edit.ContactAddressesFormPart'>]
context_object_name = 'contact'
form_part_class_provide_key = 'admin_contact_form_part'
form_valid(form)[source]
get_toolbar()[source]
model

alias of Contact

template_name = 'shoop/admin/contacts/edit.jinja'
Submodules
shoop.admin.modules.contacts.dashboard module
shoop.admin.modules.contacts.dashboard.get_active_customers_block(request)[source]
Module contents
class shoop.admin.modules.contacts.ContactModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_dashboard_blocks(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.demo package
Module contents
class shoop.admin.modules.demo.DemoModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_urls()[source]
check_demo_optin(request)[source]

Check whether or not the user has opted in to see demo content. This may be toggled with ?demo=0 or ?demo=1, and it’s a persistent session flag.

Parameters:request (django.http.HttpRequest) – HTTP request
Returns:Opt-in flag
Return type:bool
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_notifications(request)[source]
get_dashboard_blocks(request)[source]
get_activity(request, cutoff)[source]
shoop.admin.modules.manufacturers package
Subpackages
shoop.admin.modules.manufacturers.views package
Submodules
shoop.admin.modules.manufacturers.views.edit module
class shoop.admin.modules.manufacturers.views.edit.ManufacturerForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of Manufacturer

exclude = ('identifier', 'created_on')
ManufacturerForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655ba99160>), ('url', <django.forms.fields.CharField object at 0x7f655b2c4a20>)])
ManufacturerForm.declared_fields = OrderedDict()
ManufacturerForm.media
class shoop.admin.modules.manufacturers.views.edit.ManufacturerEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Manufacturer

form_class

alias of ManufacturerForm

template_name = 'shoop/admin/manufacturers/edit.jinja'
context_object_name = 'manufacturer'
shoop.admin.modules.manufacturers.views.list module
class shoop.admin.modules.manufacturers.views.list.ManufacturerListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Manufacturer

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b4277f0>]
Module contents
class shoop.admin.modules.manufacturers.views.ManufacturerEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'manufacturer'
form_class

alias of ManufacturerForm

model

alias of Manufacturer

template_name = 'shoop/admin/manufacturers/edit.jinja'
class shoop.admin.modules.manufacturers.views.ManufacturerListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b4277f0>]
model

alias of Manufacturer

Module contents
class shoop.admin.modules.manufacturers.ManufacturerModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.media package
Submodules
shoop.admin.modules.media.utils module
shoop.admin.modules.media.utils.delete_folder(folder)[source]

Delete a Filer folder and move files and subfolders up to the parent.

Parameters:folder (filer.models.Folder) – Folder
Returns:Success message
Return type:str
shoop.admin.modules.media.views module
shoop.admin.modules.media.views.get_folder_name(folder)[source]
class shoop.admin.modules.media.views.MediaBrowserView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

A view for browsing media.

Most of this is just a JSON API that the Javascript (static_src/media/browser) uses.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/media/browser.jinja'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_context_data(**kwargs)[source]
get(request, *args, **kwargs)[source]
post(request, *args, **kwargs)[source]
handle_get_folders(data)[source]
handle_post_new_folder(data)[source]
handle_get_folder(data)[source]
handle_upload()[source]
handle_post_rename_folder(data)[source]
handle_post_delete_folder(data)[source]
handle_post_rename_file(data)[source]
handle_post_delete_file(data)[source]
handle_post_move_file(data)[source]
Module contents
class shoop.admin.modules.media.MediaModule[source]

Bases: shoop.admin.base.AdminModule

A module for handling site media. Basically a frontend for the Django-Filer app.

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
shoop.admin.modules.methods package
Subpackages
shoop.admin.modules.methods.views package
Submodules
shoop.admin.modules.methods.views.edit module
class shoop.admin.modules.methods.views.edit.MethodEditToolbar(view_object)[source]

Bases: shoop.admin.toolbar.Toolbar

build_detail_button(method)[source]
class shoop.admin.modules.methods.views.edit.ShippingMethodEditView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit._BaseMethodEditView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ShippingMethod

action_url_name_prefix = 'method.shipping'
class shoop.admin.modules.methods.views.edit.PaymentMethodEditView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit._BaseMethodEditView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of PaymentMethod

action_url_name_prefix = 'method.payment'
shoop.admin.modules.methods.views.edit_detail module
class shoop.admin.modules.methods.views.edit_detail.ShippingMethodEditDetailView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit_detail._BaseMethodDetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ShippingMethod

class shoop.admin.modules.methods.views.edit_detail.PaymentMethodEditDetailView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit_detail._BaseMethodDetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of PaymentMethod

shoop.admin.modules.methods.views.list module
class shoop.admin.modules.methods.views.list.ShippingMethodListView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.list._BaseMethodListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ShippingMethod

class shoop.admin.modules.methods.views.list.PaymentMethodListView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.list._BaseMethodListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of PaymentMethod

Module contents
class shoop.admin.modules.methods.views.ShippingMethodEditView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit._BaseMethodEditView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

action_url_name_prefix = 'method.shipping'
model

alias of ShippingMethod

class shoop.admin.modules.methods.views.ShippingMethodEditDetailView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit_detail._BaseMethodDetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ShippingMethod

class shoop.admin.modules.methods.views.ShippingMethodListView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.list._BaseMethodListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ShippingMethod

class shoop.admin.modules.methods.views.PaymentMethodEditView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit._BaseMethodEditView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

action_url_name_prefix = 'method.payment'
model

alias of PaymentMethod

class shoop.admin.modules.methods.views.PaymentMethodEditDetailView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.edit_detail._BaseMethodDetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of PaymentMethod

class shoop.admin.modules.methods.views.PaymentMethodListView(**kwargs)[source]

Bases: shoop.admin.modules.methods.views.list._BaseMethodListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of PaymentMethod

Module contents
class shoop.admin.modules.methods.MethodModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.orders package
Subpackages
shoop.admin.modules.orders.views package
Submodules
shoop.admin.modules.orders.views.create module
shoop.admin.modules.orders.views.create.create_order_from_state(state, **kwargs)[source]
shoop.admin.modules.orders.views.create.create_source_from_state(state, **kwargs)[source]
shoop.admin.modules.orders.views.create.encode_address(address)[source]
shoop.admin.modules.orders.views.create.encode_shop(shop)[source]
shoop.admin.modules.orders.views.create.encode_method_extras(method)[source]
shoop.admin.modules.orders.views.create.encode_method(method)[source]
shoop.admin.modules.orders.views.create.encode_line(line)[source]
shoop.admin.modules.orders.views.create.get_price_info(shop, customer, product, quantity)[source]
class shoop.admin.modules.orders.views.create.OrderCreateView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

template_name = 'shoop/admin/orders/create.jinja'
context_object_name = 'order'
title = 'Create Order'
get_context_data(**kwargs)[source]
get_config()[source]
dispatch(request, *args, **kwargs)[source]
dispatch_command(request)[source]
handle_product_data(request)[source]
handle_customer_data(request)[source]
handle_source_data(request)[source]
handle_create(request)[source]
shoop.admin.modules.orders.views.detail module
class shoop.admin.modules.orders.views.detail.OrderDetailView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

template_name = 'shoop/admin/orders/detail.jinja'
context_object_name = 'order'
get_toolbar()[source]
get_context_data(**kwargs)[source]
class shoop.admin.modules.orders.views.detail.OrderSetStatusView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

get(request, *args, **kwargs)[source]
post(request, *args, **kwargs)[source]
shoop.admin.modules.orders.views.list module
class shoop.admin.modules.orders.views.list.OrderListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b4099e8>, <shoop.admin.utils.picotable.Column object at 0x7f655b409e10>, <shoop.admin.utils.picotable.Column object at 0x7f655b409ba8>, <shoop.admin.utils.picotable.Column object at 0x7f655b4097b8>, <shoop.admin.utils.picotable.Column object at 0x7f655b4097f0>, <shoop.admin.utils.picotable.Column object at 0x7f655b409e80>, <shoop.admin.utils.picotable.Column object at 0x7f655b409908>]
get_queryset()[source]
format_order_date(instance, *args, **kwargs)[source]
format_taxful_total_price(instance, *args, **kwargs)[source]
get_object_abstract(instance, item)[source]
shoop.admin.modules.orders.views.shipment module
class shoop.admin.modules.orders.views.shipment.OrderCreateShipmentView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

template_name = 'shoop/admin/orders/create_shipment.jinja'
context_object_name = 'order'
form_class

alias of Form

get_context_data(**kwargs)[source]
get_form_kwargs()[source]
get_form(form_class=None)
form_invalid(form)[source]
form_valid(form)[source]
Module contents
class shoop.admin.modules.orders.views.OrderDetailView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'order'
get_context_data(**kwargs)[source]
get_toolbar()[source]
model

alias of Order

template_name = 'shoop/admin/orders/detail.jinja'
class shoop.admin.modules.orders.views.OrderListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b4099e8>, <shoop.admin.utils.picotable.Column object at 0x7f655b409e10>, <shoop.admin.utils.picotable.Column object at 0x7f655b409ba8>, <shoop.admin.utils.picotable.Column object at 0x7f655b4097b8>, <shoop.admin.utils.picotable.Column object at 0x7f655b4097f0>, <shoop.admin.utils.picotable.Column object at 0x7f655b409e80>, <shoop.admin.utils.picotable.Column object at 0x7f655b409908>]
format_order_date(instance, *args, **kwargs)[source]
format_taxful_total_price(instance, *args, **kwargs)[source]
get_object_abstract(instance, item)[source]
get_queryset()[source]
model

alias of Order

class shoop.admin.modules.orders.views.OrderCreateShipmentView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'order'
form_class

alias of Form

form_invalid(form)[source]
form_valid(form)[source]
get_context_data(**kwargs)[source]
get_form(form_class=None)
get_form_kwargs()[source]
model

alias of Order

template_name = 'shoop/admin/orders/create_shipment.jinja'
class shoop.admin.modules.orders.views.OrderSetStatusView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get(request, *args, **kwargs)[source]
model

alias of Order

post(request, *args, **kwargs)[source]
class shoop.admin.modules.orders.views.OrderCreateView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'order'
dispatch(request, *args, **kwargs)[source]
dispatch_command(request)[source]
get_config()[source]
get_context_data(**kwargs)[source]
handle_create(request)[source]
handle_customer_data(request)[source]
handle_product_data(request)[source]
handle_source_data(request)[source]
model

alias of Order

template_name = 'shoop/admin/orders/create.jinja'
title = 'Create Order'
Submodules
shoop.admin.modules.orders.dashboard module
shoop.admin.modules.orders.dashboard.get_orders_by_currency(currency)[source]
class shoop.admin.modules.orders.dashboard.OrderValueChartDashboardBlock(id, currency, **kwargs)[source]

Bases: shoop.admin.dashboard.blocks.DashboardChartBlock

get_chart()[source]
shoop.admin.modules.orders.dashboard.get_subtitle(count)[source]
shoop.admin.modules.orders.dashboard.get_sales_of_the_day_block(request, currency)[source]
shoop.admin.modules.orders.dashboard.get_lifetime_sales_block(request, currency)[source]
shoop.admin.modules.orders.dashboard.get_avg_purchase_size_block(request, currency)[source]
shoop.admin.modules.orders.dashboard.get_open_orders_block(request, currency)[source]
shoop.admin.modules.orders.dashboard.get_order_value_chart_dashboard_block(request, currency)[source]
shoop.admin.modules.orders.json_order_creator module
class shoop.admin.modules.orders.json_order_creator.JsonOrderCreator[source]

Bases: object

static safe_get_first(model, **lookup)[source]
add_error(error)[source]
is_valid
errors
create_source_from_state(state, creator=None, save=False)[source]

Create an order source from a state dict unserialized from JSON.

Parameters:
  • state (dict) – State dictionary
  • creator (django.contrib.auth.models.User|None) – Creator user
  • save (boolean) – Flag whether order customer and addresses is saved to database
Returns:

The created order source, or None if something failed along the way

Return type:

OrderSource|None

create_order_from_state(state, creator=None)[source]

Create an order from a state dict unserialized from JSON.

Parameters:
  • state (dict) – State dictionary
  • creator (django.contrib.auth.models.User|None) – Creator user
Returns:

The created order, or None if something failed along the way

Return type:

Order|None

Module contents
class shoop.admin.modules.orders.OrderModule(currency=None, *args, **kwargs)[source]

Bases: shoop.admin.currencybound.CurrencyBound, shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_dashboard_blocks(request)[source]
get_notifications(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.product_types package
Subpackages
shoop.admin.modules.product_types.views package
Submodules
shoop.admin.modules.product_types.views.edit module
class shoop.admin.modules.product_types.views.edit.ProductTypeForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of ProductType

exclude = ()
widgets = {'attributes': <class 'django.forms.widgets.CheckboxSelectMultiple'>}
ProductTypeForm.base_fields = OrderedDict([('attributes', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a828240>), ('name', <django.forms.fields.CharField object at 0x7f655a828940>)])
ProductTypeForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a828940>)])
ProductTypeForm.media
class shoop.admin.modules.product_types.views.edit.ProductTypeEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ProductType

form_class

alias of ProductTypeForm

template_name = 'shoop/admin/product_types/edit.jinja'
context_object_name = 'product_type'
shoop.admin.modules.product_types.views.list module
class shoop.admin.modules.product_types.views.list.ProductTypeListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ProductType

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a4b29b0>, <shoop.admin.utils.picotable.Column object at 0x7f655a4b2940>]
get_queryset()[source]
Module contents
class shoop.admin.modules.product_types.views.ProductTypeEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'product_type'
form_class

alias of ProductTypeForm

model

alias of ProductType

template_name = 'shoop/admin/product_types/edit.jinja'
class shoop.admin.modules.product_types.views.ProductTypeListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a4b29b0>, <shoop.admin.utils.picotable.Column object at 0x7f655a4b2940>]
get_queryset()[source]
model

alias of ProductType

Module contents
class shoop.admin.modules.product_types.ProductTypeModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.products package
Subpackages
shoop.admin.modules.products.views package
Subpackages
shoop.admin.modules.products.views.variation package
Submodules
shoop.admin.modules.products.views.variation.edit_variation module
class shoop.admin.modules.products.views.variation.edit_variation.VariationChildrenFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = 0
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.products.views.variation.edit_variation.VariationVariablesFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = 1
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.products.views.variation.edit_variation.ProductVariationViewToolbar(view)[source]

Bases: shoop.admin.toolbar.Toolbar

class shoop.admin.modules.products.views.variation.edit_variation.ProductVariationView(**kwargs)[source]

Bases: shoop.admin.form_part.FormPartsViewMixin, django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

template_name = 'shoop/admin/products/variation/edit.jinja'
context_object_name = 'product'
form_class

alias of Form

dispatch(request, *args, **kwargs)[source]
get_breadcrumb_parents()[source]
post(request, *args, **kwargs)[source]
get_form_part_classes()[source]
get_context_data(**kwargs)[source]
form_valid(form)[source]
get_success_url()[source]
dispatch_command(request, command)[source]
shoop.admin.modules.products.views.variation.simple_variation_forms module
class shoop.admin.modules.products.views.variation.simple_variation_forms.SimpleVariationChildForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

base_fields = OrderedDict([('child', <django.forms.models.ModelChoiceField object at 0x7f655a3630b8>)])
declared_fields = OrderedDict([('child', <django.forms.models.ModelChoiceField object at 0x7f655a3630b8>)])
media
class shoop.admin.modules.products.views.variation.simple_variation_forms.SimpleVariationChildFormSet(**kwargs)[source]

Bases: django.forms.formsets.BaseFormSet

save()[source]
get_selected_and_unlinked()[source]
shoop.admin.modules.products.views.variation.variable_variation_forms module
class shoop.admin.modules.products.views.variation.variable_variation_forms.VariableVariationChildrenForm(**kwargs)[source]

Bases: django.forms.forms.Form

save()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.admin.modules.products.views.variation.variable_variation_forms.VariationVariablesDataForm(**kwargs)[source]

Bases: django.forms.forms.Form

get_variable_data()[source]
get_editor_args()[source]
process_var_datum(var_datum)[source]
process_val_datum(var, val_datum)[source]
save()[source]
base_fields = OrderedDict([('data', <django.forms.fields.CharField object at 0x7f655a3632e8>)])
declared_fields = OrderedDict([('data', <django.forms.fields.CharField object at 0x7f655a3632e8>)])
media
Module contents
Submodules
shoop.admin.modules.products.views.delete module
class shoop.admin.modules.products.views.delete.ProductDeleteView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

context_object_name = 'product'
get(request, *args, **kwargs)[source]
post(request, *args, **kwargs)[source]
shoop.admin.modules.products.views.edit module
class shoop.admin.modules.products.views.edit.ProductBaseFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -1000
get_form_defs()[source]
form_valid(form)[source]
get_initial()[source]
class shoop.admin.modules.products.views.edit.ShopProductFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -900
get_shop_instance(shop)[source]
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.products.views.edit.ProductAttributeFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = -800
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.products.views.edit.BaseProductMediaFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.modules.products.views.edit.ProductMediaFormPart(request, object=None)[source]

Bases: shoop.admin.modules.products.views.edit.BaseProductMediaFormPart

name = 'media'
priority = -700
formset

alias of ProductMediaFormSet

class shoop.admin.modules.products.views.edit.ProductImageMediaFormPart(request, object=None)[source]

Bases: shoop.admin.modules.products.views.edit.BaseProductMediaFormPart

name = 'images'
priority = -600
formset

alias of ProductImageMediaFormSet

class shoop.admin.modules.products.views.edit.ProductEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

template_name = 'shoop/admin/products/edit.jinja'
context_object_name = 'product'
base_form_part_classes = [<class 'shoop.admin.modules.products.views.edit.ProductBaseFormPart'>, <class 'shoop.admin.modules.products.views.edit.ShopProductFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductAttributeFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductImageMediaFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductMediaFormPart'>]
form_part_class_provide_key = 'admin_product_form_part'
form_valid(form)[source]
get_toolbar()[source]
get_context_data(**kwargs)[source]
shoop.admin.modules.products.views.edit_cross_sell module
class shoop.admin.modules.products.views.edit_cross_sell.ProductCrossSellForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of ProductCrossSell

fields = ('product2', 'weight', 'type')
ProductCrossSellForm.save(commit=True)[source]
ProductCrossSellForm.base_fields = OrderedDict([('product2', <django.forms.models.ModelChoiceField object at 0x7f655a355780>), ('weight', <django.forms.fields.IntegerField object at 0x7f655a355940>), ('type', <enumfields.forms.EnumChoiceField object at 0x7f655a3559e8>)])
ProductCrossSellForm.declared_fields = OrderedDict()
ProductCrossSellForm.media
class shoop.admin.modules.products.views.edit_cross_sell.ProductCrossSellFormSet(*args, **kwargs)[source]

Bases: django.forms.models.BaseModelFormSet

validate_min = False
min_num = 0
validate_max = False
max_num = 1000
absolute_max = 1000
model

alias of ProductMedia

can_delete = True
can_order = False
extra = 5
form(**kwargs)[source]
class shoop.admin.modules.products.views.edit_cross_sell.ProductCrossSellEditView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

template_name = 'shoop/admin/products/edit_cross_sell.jinja'
context_object_name = 'product'
form_class

alias of ProductCrossSellFormSet

get_breadcrumb_parents()[source]
get_context_data(**kwargs)[source]
get_form_kwargs()[source]
form_valid(form)[source]
shoop.admin.modules.products.views.edit_media module
class shoop.admin.modules.products.views.edit_media.ProductMediaForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of ProductMedia

fields = ('shops', 'kind', 'file', 'external_url', 'ordering', 'enabled', 'public', 'purchased', 'title', 'description')
ProductMediaForm.pre_master_save(instance)[source]
ProductMediaForm.base_fields = OrderedDict([('shops', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a355f28>), ('kind', <enumfields.forms.EnumChoiceField object at 0x7f655a35c128>), ('file', <filer.fields.file.AdminFileFormField object at 0x7f655a35c1d0>), ('external_url', <django.forms.fields.URLField object at 0x7f655a35c390>), ('ordering', <django.forms.fields.IntegerField object at 0x7f655a35c4a8>), ('enabled', <django.forms.fields.BooleanField object at 0x7f655a35c550>), ('public', <django.forms.fields.BooleanField object at 0x7f655a35c5f8>), ('purchased', <django.forms.fields.BooleanField object at 0x7f655a35c6a0>), ('title', <django.forms.fields.CharField object at 0x7f655a355d68>), ('description', <django.forms.fields.CharField object at 0x7f655a355e80>)])
ProductMediaForm.declared_fields = OrderedDict([('title', <django.forms.fields.CharField object at 0x7f655a355d68>), ('description', <django.forms.fields.CharField object at 0x7f655a355e80>)])
ProductMediaForm.media
class shoop.admin.modules.products.views.edit_media.ProductMediaFormSet(*args, **kwargs)[source]

Bases: django.forms.models.BaseModelFormSet

validate_min = False
min_num = 0
validate_max = False
max_num = 1000
absolute_max = 1000
model

alias of ProductMedia

can_delete = True
can_order = False
extra = 5
form(**kwargs)[source]
class shoop.admin.modules.products.views.edit_media.ProductMediaEditView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

A view for editing all the media for a product, including attachments that are not just images.

Currently sort of utilitarian and confusing.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

template_name = 'shoop/admin/products/edit_media.jinja'
context_object_name = 'product'
form_class

alias of ProductMediaFormSet

get_breadcrumb_parents()[source]
get_context_data(**kwargs)[source]
get_form_kwargs()[source]
form_valid(form)[source]
shoop.admin.modules.products.views.forms module
class shoop.admin.modules.products.views.forms.ProductBaseForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of Product

fields = ('accounting_identifier', 'barcode', 'category', 'cost_center', 'depth', 'gross_weight', 'gtin', 'height', 'manufacturer', 'net_weight', 'profit_center', 'sales_unit', 'shipping_mode', 'sku', 'tax_class', 'type', 'width', 'description', 'keywords', 'name', 'status_text', 'variation_name')
widgets = {'keywords': <django.forms.widgets.TextInput object at 0x7f655a3af2e8>}
ProductBaseForm.base_fields = OrderedDict([('accounting_identifier', <django.forms.fields.CharField object at 0x7f655a3afdd8>), ('barcode', <django.forms.fields.CharField object at 0x7f655a4ad358>), ('category', <django.forms.models.ModelChoiceField object at 0x7f655a3c0160>), ('cost_center', <django.forms.fields.CharField object at 0x7f655a3c0048>), ('depth', <django.forms.fields.DecimalField object at 0x7f655a3c0518>), ('gross_weight', <django.forms.fields.DecimalField object at 0x7f655a3c06d8>), ('gtin', <django.forms.fields.CharField object at 0x7f655a3a60b8>), ('height', <django.forms.fields.DecimalField object at 0x7f655a3c0438>), ('manufacturer', <django.forms.models.ModelChoiceField object at 0x7f655a3c07b8>), ('net_weight', <django.forms.fields.DecimalField object at 0x7f655a3c05f8>), ('profit_center', <django.forms.fields.CharField object at 0x7f655a3afef0>), ('sales_unit', <django.forms.models.ModelChoiceField object at 0x7f655a3af8d0>), ('shipping_mode', <enumfields.forms.EnumChoiceField object at 0x7f655a3af828>), ('sku', <django.forms.fields.CharField object at 0x7f655a4394a8>), ('tax_class', <django.forms.models.ModelChoiceField object at 0x7f655a3afa90>), ('type', <django.forms.models.ModelChoiceField object at 0x7f655a44b7f0>), ('width', <django.forms.fields.DecimalField object at 0x7f655a3c0320>), ('description', <django.forms.fields.CharField object at 0x7f655a3af4e0>), ('keywords', <django.forms.fields.CharField object at 0x7f655a3af588>), ('name', <django.forms.fields.CharField object at 0x7f655a3af3c8>), ('status_text', <django.forms.fields.CharField object at 0x7f655a3af5f8>), ('variation_name', <django.forms.fields.CharField object at 0x7f655a3af710>)])
ProductBaseForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a3af3c8>), ('description', <django.forms.fields.CharField object at 0x7f655a3af4e0>), ('keywords', <django.forms.fields.CharField object at 0x7f655a3af588>), ('status_text', <django.forms.fields.CharField object at 0x7f655a3af5f8>), ('variation_name', <django.forms.fields.CharField object at 0x7f655a3af710>)])
ProductBaseForm.media
class shoop.admin.modules.products.views.forms.ShopProductForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of ShopProduct

fields = ('default_price_value', 'suppliers', 'visible', 'listed', 'purchasable', 'searchable', 'visibility_limit', 'visibility_groups', 'purchase_multiple', 'minimum_purchase_quantity', 'limit_shipping_methods', 'limit_payment_methods', 'shipping_methods', 'payment_methods', 'primary_category', 'categories')
ShopProductForm.clean_minimum_purchase_quantity()[source]
ShopProductForm.base_fields = OrderedDict([('default_price_value', <django.forms.fields.DecimalField object at 0x7f655a3c6ac8>), ('suppliers', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c09b0>), ('visible', <django.forms.fields.BooleanField object at 0x7f655a3c0b70>), ('listed', <django.forms.fields.BooleanField object at 0x7f655a3c0c18>), ('purchasable', <django.forms.fields.BooleanField object at 0x7f655a3c0cc0>), ('searchable', <django.forms.fields.BooleanField object at 0x7f655a3c0d68>), ('visibility_limit', <enumfields.forms.EnumChoiceField object at 0x7f655a3c0e10>), ('visibility_groups', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c0eb8>), ('purchase_multiple', <django.forms.fields.DecimalField object at 0x7f655a3c60b8>), ('minimum_purchase_quantity', <django.forms.fields.DecimalField object at 0x7f655a3c6198>), ('limit_shipping_methods', <django.forms.fields.BooleanField object at 0x7f655a3c6278>), ('limit_payment_methods', <django.forms.fields.BooleanField object at 0x7f655a3c6320>), ('shipping_methods', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c63c8>), ('payment_methods', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c6588>), ('primary_category', <django.forms.models.ModelChoiceField object at 0x7f655a3c6748>), ('categories', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c6908>)])
ShopProductForm.declared_fields = OrderedDict()
ShopProductForm.media
class shoop.admin.modules.products.views.forms.ProductAttributesForm(**kwargs)[source]

Bases: django.forms.forms.Form

save()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.admin.modules.products.views.forms.BaseProductMediaForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of ProductMedia

fields = ('file', 'ordering', 'external_url', 'public', 'title', 'description', 'purchased', 'shops', 'kind')
BaseProductMediaForm.get_thumbnail(request)[source]

Get thumbnail url.

If thumbnail creation fails for whatever reason, an error message is displayed for user.

BaseProductMediaForm.pre_master_save(instance)[source]
BaseProductMediaForm.base_fields = OrderedDict([('file', <filer.fields.file.AdminFileFormField object at 0x7f655a3cc080>), ('ordering', <django.forms.fields.IntegerField object at 0x7f655a3cc390>), ('external_url', <django.forms.fields.URLField object at 0x7f655a3cc278>), ('public', <django.forms.fields.BooleanField object at 0x7f655a3cc438>), ('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>), ('purchased', <django.forms.fields.BooleanField object at 0x7f655a3cc4e0>), ('shops', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3c6dd8>), ('kind', <enumfields.forms.EnumChoiceField object at 0x7f655a3c6f98>)])
BaseProductMediaForm.declared_fields = OrderedDict([('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>)])
BaseProductMediaForm.media
class shoop.admin.modules.products.views.forms.BaseProductMediaFormSet(*args, **kwargs)[source]

Bases: django.forms.models.BaseModelFormSet

validate_min = False
min_num = 0
validate_max = False
max_num = 1000
absolute_max = 1000
model

alias of ProductMedia

can_delete = True
can_order = False
extra = 1
allowed_media_kinds = []
get_queryset()[source]
form(**kwargs)[source]
class shoop.admin.modules.products.views.forms.ProductMediaForm(**kwargs)[source]

Bases: shoop.admin.modules.products.views.forms.BaseProductMediaForm

clean_external_url()[source]
base_fields = OrderedDict([('file', <filer.fields.file.AdminFileFormField object at 0x7f655a3cc828>), ('ordering', <django.forms.fields.IntegerField object at 0x7f655a3ccb00>), ('external_url', <django.forms.fields.URLField object at 0x7f655a3cc9e8>), ('public', <django.forms.fields.BooleanField object at 0x7f655a3ccba8>), ('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>), ('purchased', <django.forms.fields.BooleanField object at 0x7f655a3ccc50>), ('shops', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3cc5c0>), ('kind', <enumfields.forms.EnumChoiceField object at 0x7f655a3cc780>)])
declared_fields = OrderedDict([('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>)])
media
class shoop.admin.modules.products.views.forms.ProductMediaFormSet(*args, **kwargs)[source]

Bases: shoop.admin.modules.products.views.forms.BaseProductMediaFormSet

form_class

alias of ProductMediaForm

allowed_media_kinds = [<ProductMediaKind.GENERIC_FILE: 1>, <ProductMediaKind.DOCUMENTATION: 3>, <ProductMediaKind.SAMPLE: 4>]
class shoop.admin.modules.products.views.forms.ProductImageMediaForm(**kwargs)[source]

Bases: shoop.admin.modules.products.views.forms.BaseProductMediaForm

clean_file()[source]
save(commit=True)[source]
base_fields = OrderedDict([('file', <filer.fields.file.AdminFileFormField object at 0x7f655a355080>), ('ordering', <django.forms.fields.IntegerField object at 0x7f655a355358>), ('external_url', <django.forms.fields.URLField object at 0x7f655a355240>), ('public', <django.forms.fields.BooleanField object at 0x7f655a355400>), ('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>), ('purchased', <django.forms.fields.BooleanField object at 0x7f655a3554a8>), ('shops', <django.forms.models.ModelMultipleChoiceField object at 0x7f655a3ccdd8>), ('kind', <enumfields.forms.EnumChoiceField object at 0x7f655a3ccf98>), ('is_primary', <django.forms.fields.BooleanField object at 0x7f655a3cc588>)])
declared_fields = OrderedDict([('title', <django.forms.fields.CharField object at 0x7f655a3c6be0>), ('description', <django.forms.fields.CharField object at 0x7f655a3c6cf8>), ('is_primary', <django.forms.fields.BooleanField object at 0x7f655a3cc588>)])
media
class shoop.admin.modules.products.views.forms.ProductImageMediaFormSet(*args, **kwargs)[source]

Bases: shoop.admin.modules.products.views.forms.ProductMediaFormSet

allowed_media_kinds = [<ProductMediaKind.IMAGE: 2>]
form_class

alias of ProductImageMediaForm

save(commit=True)[source]

Save the form.

In addition add the first saved image as primary image for the product if none is selected as such.

shoop.admin.modules.products.views.list module
class shoop.admin.modules.products.views.list.ProductListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Product

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a35c7b8>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c898>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c908>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c9b0>, <shoop.admin.utils.picotable.Column object at 0x7f655a35ca20>]
get_queryset()[source]
get_object_abstract(instance, item)[source]
shoop.admin.modules.products.views.toolbars module
class shoop.admin.modules.products.views.toolbars.EditProductToolbar(view)[source]

Bases: shoop.admin.toolbar.Toolbar

Module contents
class shoop.admin.modules.products.views.ProductCrossSellEditView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'product'
form_class

alias of ProductCrossSellFormSet

form_valid(form)[source]
get_breadcrumb_parents()[source]
get_context_data(**kwargs)[source]
get_form_kwargs()[source]
model

alias of Product

template_name = 'shoop/admin/products/edit_cross_sell.jinja'
class shoop.admin.modules.products.views.ProductDeleteView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'product'
get(request, *args, **kwargs)[source]
model

alias of Product

post(request, *args, **kwargs)[source]
class shoop.admin.modules.products.views.ProductEditView(**kwargs)[source]

Bases: shoop.admin.form_part.SaveFormPartsMixin, shoop.admin.form_part.FormPartsViewMixin, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

base_form_part_classes = [<class 'shoop.admin.modules.products.views.edit.ProductBaseFormPart'>, <class 'shoop.admin.modules.products.views.edit.ShopProductFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductAttributeFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductImageMediaFormPart'>, <class 'shoop.admin.modules.products.views.edit.ProductMediaFormPart'>]
context_object_name = 'product'
form_part_class_provide_key = 'admin_product_form_part'
form_valid(form)[source]
get_context_data(**kwargs)[source]
get_toolbar()[source]
model

alias of Product

template_name = 'shoop/admin/products/edit.jinja'
class shoop.admin.modules.products.views.ProductListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a35c7b8>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c898>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c908>, <shoop.admin.utils.picotable.Column object at 0x7f655a35c9b0>, <shoop.admin.utils.picotable.Column object at 0x7f655a35ca20>]
get_object_abstract(instance, item)[source]
get_queryset()[source]
model

alias of Product

class shoop.admin.modules.products.views.ProductVariationView(**kwargs)[source]

Bases: shoop.admin.form_part.FormPartsViewMixin, django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'product'
dispatch(request, *args, **kwargs)[source]
dispatch_command(request, command)[source]
form_class

alias of Form

form_valid(form)[source]
get_breadcrumb_parents()[source]
get_context_data(**kwargs)[source]
get_form_part_classes()[source]
get_success_url()[source]
model

alias of Product

post(request, *args, **kwargs)[source]
template_name = 'shoop/admin/products/variation/edit.jinja'
class shoop.admin.modules.products.views.ProductMediaEditView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

A view for editing all the media for a product, including attachments that are not just images.

Currently sort of utilitarian and confusing.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'product'
form_class

alias of ProductMediaFormSet

form_valid(form)[source]
get_breadcrumb_parents()[source]
get_context_data(**kwargs)[source]
get_form_kwargs()[source]
model

alias of Product

template_name = 'shoop/admin/products/edit_media.jinja'
Module contents
class shoop.admin.modules.products.ProductModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.sales_units package
Subpackages
shoop.admin.modules.sales_units.views package
Submodules
shoop.admin.modules.sales_units.views.edit module
class shoop.admin.modules.sales_units.views.edit.SalesUnitForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of SalesUnit

exclude = ()
SalesUnitForm.base_fields = OrderedDict([('decimals', <django.forms.fields.IntegerField object at 0x7f655a0a1e10>), ('name', <django.forms.fields.CharField object at 0x7f655a063828>), ('short_name', <django.forms.fields.CharField object at 0x7f655a0a14a8>)])
SalesUnitForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a063828>), ('short_name', <django.forms.fields.CharField object at 0x7f655a0a14a8>)])
SalesUnitForm.media
class shoop.admin.modules.sales_units.views.edit.SalesUnitEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of SalesUnit

form_class

alias of SalesUnitForm

template_name = 'shoop/admin/sales_units/edit.jinja'
context_object_name = 'sales_unit'
shoop.admin.modules.sales_units.views.list module
class shoop.admin.modules.sales_units.views.list.SalesUnitListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of SalesUnit

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a0a15c0>, <shoop.admin.utils.picotable.Column object at 0x7f655a0a1cc0>, <shoop.admin.utils.picotable.Column object at 0x7f655a0962b0>]
get_queryset()[source]
Module contents
class shoop.admin.modules.sales_units.views.SalesUnitEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'sales_unit'
form_class

alias of SalesUnitForm

model

alias of SalesUnit

template_name = 'shoop/admin/sales_units/edit.jinja'
class shoop.admin.modules.sales_units.views.SalesUnitListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a0a15c0>, <shoop.admin.utils.picotable.Column object at 0x7f655a0a1cc0>, <shoop.admin.utils.picotable.Column object at 0x7f655a0962b0>]
get_queryset()[source]
model

alias of SalesUnit

Module contents
class shoop.admin.modules.sales_units.SalesUnitModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.shops package
Subpackages
shoop.admin.modules.shops.views package
Submodules
shoop.admin.modules.shops.views.edit module
class shoop.admin.modules.shops.views.edit.ShopForm(**kwargs)[source]

Bases: shoop.core.utils.form_mixins.ProtectedFieldsMixin, shoop.utils.multilanguage_model_form.MultiLanguageModelForm

change_protect_field_text = <django.utils.functional.lazy.<locals>.__proxy__ object>
class Meta[source]

Bases: object

model

alias of Shop

exclude = ('owner', 'options')
ShopForm.base_fields = OrderedDict([('domain', <django.forms.fields.CharField object at 0x7f655a07a048>), ('status', <enumfields.forms.EnumChoiceField object at 0x7f655a00f400>), ('currency', <django.forms.fields.CharField object at 0x7f655a00f128>), ('prices_include_tax', <django.forms.fields.BooleanField object at 0x7f655a00fc18>), ('logo', <filer.fields.image.AdminImageFormField object at 0x7f655a00f748>), ('maintenance_mode', <django.forms.fields.BooleanField object at 0x7f655a00f668>), ('name', <django.forms.fields.CharField object at 0x7f655a07a5c0>), ('public_name', <django.forms.fields.CharField object at 0x7f655a07a978>), ('maintenance_message', <django.forms.fields.CharField object at 0x7f655a07a438>)])
ShopForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a07a5c0>), ('public_name', <django.forms.fields.CharField object at 0x7f655a07a978>), ('maintenance_message', <django.forms.fields.CharField object at 0x7f655a07a438>)])
ShopForm.media
class shoop.admin.modules.shops.views.edit.ShopEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Shop

form_class

alias of ShopForm

template_name = 'shoop/admin/shops/edit.jinja'
context_object_name = 'shop'
add_form_errors_as_messages = True
get_object(queryset=None)[source]
get_toolbar()[source]
shoop.admin.modules.shops.views.list module
class shoop.admin.modules.shops.views.list.ShopListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Shop

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a01ebe0>, <shoop.admin.utils.picotable.Column object at 0x7f655a01e828>, <shoop.admin.utils.picotable.Column object at 0x7f6559f95160>, <shoop.admin.utils.picotable.Column object at 0x7f6559f95978>]
get_toolbar()[source]
Module contents
class shoop.admin.modules.shops.views.ShopEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

add_form_errors_as_messages = True
context_object_name = 'shop'
form_class

alias of ShopForm

get_object(queryset=None)[source]
get_toolbar()[source]
model

alias of Shop

template_name = 'shoop/admin/shops/edit.jinja'
class shoop.admin.modules.shops.views.ShopListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a01ebe0>, <shoop.admin.utils.picotable.Column object at 0x7f655a01e828>, <shoop.admin.utils.picotable.Column object at 0x7f6559f95160>, <shoop.admin.utils.picotable.Column object at 0x7f6559f95978>]
get_toolbar()[source]
model

alias of Shop

Module contents
class shoop.admin.modules.shops.ShopModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.suppliers package
Subpackages
shoop.admin.modules.suppliers.views package
Submodules
shoop.admin.modules.suppliers.views.edit module
class shoop.admin.modules.suppliers.views.edit.SupplierForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of Supplier

exclude = ('module_data',)
widgets = {'module_identifier': <class 'django.forms.widgets.Select'>}
SupplierForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f6559f13048>), ('type', <enumfields.forms.EnumChoiceField object at 0x7f6559ed7ac8>), ('stock_managed', <django.forms.fields.BooleanField object at 0x7f6559ed7b70>), ('module_identifier', <django.forms.fields.CharField object at 0x7f655a2b3630>)])
SupplierForm.declared_fields = OrderedDict()
SupplierForm.media
class shoop.admin.modules.suppliers.views.edit.SupplierEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Supplier

form_class

alias of SupplierForm

template_name = 'shoop/admin/suppliers/edit.jinja'
context_object_name = 'supplier'
get_form(form_class=None)[source]
shoop.admin.modules.suppliers.views.list module
class shoop.admin.modules.suppliers.views.list.SupplierListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Supplier

columns = [<shoop.admin.utils.picotable.Column object at 0x7f6559ed72b0>, <shoop.admin.utils.picotable.Column object at 0x7f6559ed7240>, <shoop.admin.utils.picotable.Column object at 0x7f6559ed71d0>]
get_module_display(instance)[source]
Module contents
class shoop.admin.modules.suppliers.views.SupplierEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'supplier'
form_class

alias of SupplierForm

get_form(form_class=None)[source]
model

alias of Supplier

template_name = 'shoop/admin/suppliers/edit.jinja'
class shoop.admin.modules.suppliers.views.SupplierListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f6559ed72b0>, <shoop.admin.utils.picotable.Column object at 0x7f6559ed7240>, <shoop.admin.utils.picotable.Column object at 0x7f6559ed71d0>]
get_module_display(instance)[source]
model

alias of Supplier

Module contents
class shoop.admin.modules.suppliers.SupplierModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.system package
Subpackages
shoop.admin.modules.system.views package
Submodules
shoop.admin.modules.system.views.telemetry module
class shoop.admin.modules.system.views.telemetry.TelemetryView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/system/telemetry.jinja'
get_context_data(**kwargs)[source]
get(request, *args, **kwargs)[source]
post(request, *args, **kwargs)[source]
Module contents
Module contents
class shoop.admin.modules.system.SystemModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_notifications(request)[source]
shoop.admin.modules.taxes package
Subpackages
shoop.admin.modules.taxes.views package
Submodules
shoop.admin.modules.taxes.views.edit module
class shoop.admin.modules.taxes.views.edit.TaxForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of Tax

fields = ['name', 'code', 'rate', 'amount_value', 'currency', 'enabled']
TaxForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a48ebe0>), ('code', <django.forms.fields.CharField object at 0x7f655a48e160>), ('rate', <shoop.admin.forms.fields.PercentageField object at 0x7f655a1a24e0>), ('amount_value', <django.forms.fields.DecimalField object at 0x7f655a48eba8>), ('currency', <django.forms.fields.CharField object at 0x7f655a472588>), ('enabled', <django.forms.fields.BooleanField object at 0x7f655a4727f0>)])
TaxForm.declared_fields = OrderedDict([('rate', <shoop.admin.forms.fields.PercentageField object at 0x7f655a1a24e0>), ('name', <django.forms.fields.CharField object at 0x7f655a48ebe0>)])
TaxForm.media
class shoop.admin.modules.taxes.views.edit.CustomerTaxGroupForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of CustomerTaxGroup

fields = ['name']
CustomerTaxGroupForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a48ea20>)])
CustomerTaxGroupForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a48ea20>)])
CustomerTaxGroupForm.media
class shoop.admin.modules.taxes.views.edit.TaxClassForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of TaxClass

fields = ['name', 'enabled']
TaxClassForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a472f98>), ('enabled', <django.forms.fields.BooleanField object at 0x7f655a472048>)])
TaxClassForm.declared_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655a472f98>)])
TaxClassForm.media
class shoop.admin.modules.taxes.views.edit.TaxEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Tax

form_class

alias of TaxForm

template_name = 'shoop/admin/taxes/edit_tax.jinja'
context_object_name = 'tax'
add_form_errors_as_messages = True
parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:tax.list'
class shoop.admin.modules.taxes.views.edit.CustomerTaxGroupEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of CustomerTaxGroup

form_class

alias of CustomerTaxGroupForm

template_name = 'shoop/admin/taxes/edit_customer_tax_group.jinja'
context_object_name = 'customer_tax_group'
parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:customer_tax_group.list'
class shoop.admin.modules.taxes.views.edit.TaxClassEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of TaxClass

template_name = 'shoop/admin/taxes/edit_tax_class.jinja'
form_class

alias of TaxClassForm

context_object_name = 'tax_class'
parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:tax_class.list'
shoop.admin.modules.taxes.views.list module
class shoop.admin.modules.taxes.views.list.TaxListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Tax

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a472748>, <shoop.admin.utils.picotable.Column object at 0x7f655a4725c0>, <shoop.admin.utils.picotable.Column object at 0x7f655a472f28>, <shoop.admin.utils.picotable.Column object at 0x7f655a472a90>]
class shoop.admin.modules.taxes.views.list.CustomerTaxGroupListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of CustomerTaxGroup

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a472e10>]
class shoop.admin.modules.taxes.views.list.TaxClassListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of TaxClass

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a4728d0>]
Module contents
class shoop.admin.modules.taxes.views.TaxClassListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a4728d0>]
model

alias of TaxClass

class shoop.admin.modules.taxes.views.TaxClassEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'tax_class'
form_class

alias of TaxClassForm

model

alias of TaxClass

parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:tax_class.list'
template_name = 'shoop/admin/taxes/edit_tax_class.jinja'
class shoop.admin.modules.taxes.views.TaxEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

add_form_errors_as_messages = True
context_object_name = 'tax'
form_class

alias of TaxForm

model

alias of Tax

parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:tax.list'
template_name = 'shoop/admin/taxes/edit_tax.jinja'
class shoop.admin.modules.taxes.views.TaxListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a472748>, <shoop.admin.utils.picotable.Column object at 0x7f655a4725c0>, <shoop.admin.utils.picotable.Column object at 0x7f655a472f28>, <shoop.admin.utils.picotable.Column object at 0x7f655a472a90>]
model

alias of Tax

class shoop.admin.modules.taxes.views.CustomerTaxGroupEditView(**kwargs)[source]

Bases: shoop.admin.modules.taxes.views.edit._Breadcrumbed, shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'customer_tax_group'
form_class

alias of CustomerTaxGroupForm

model

alias of CustomerTaxGroup

parent_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
parent_url = 'shoop_admin:customer_tax_group.list'
template_name = 'shoop/admin/taxes/edit_customer_tax_group.jinja'
class shoop.admin.modules.taxes.views.CustomerTaxGroupListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655a472e10>]
model

alias of CustomerTaxGroup

Module contents
class shoop.admin.modules.taxes.TaxModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
shoop.admin.modules.users package
Subpackages
shoop.admin.modules.users.views package
Submodules
shoop.admin.modules.users.views.detail module
class shoop.admin.modules.users.views.detail.BaseUserForm(*args, **kwargs)[source]

Bases: django.forms.models.ModelForm

save(commit=True)[source]
base_fields = OrderedDict([('password', <django.forms.fields.CharField object at 0x7f655b4687b8>), ('permission_info', <django.forms.fields.CharField object at 0x7f655b468630>)])
declared_fields = OrderedDict([('password', <django.forms.fields.CharField object at 0x7f655b4687b8>), ('permission_info', <django.forms.fields.CharField object at 0x7f655b468630>)])
media
class shoop.admin.modules.users.views.detail.UserDetailToolbar(view)[source]

Bases: shoop.admin.toolbar.Toolbar

class shoop.admin.modules.users.views.detail.UserDetailView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/users/detail.jinja'
context_object_name = 'user'
fields = ('username', 'email', 'first_name', 'last_name')
get_form_class()[source]
get_initial()[source]
get_toolbar()[source]
save_form(form)[source]
get_success_url()[source]
post(request, *args, **kwargs)[source]
dispatch(request, *args, **kwargs)[source]
shoop.admin.modules.users.views.list module
class shoop.admin.modules.users.views.list.UserListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model = 'auth.User'
columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b443390>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cada0>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cabe0>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cad68>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cab38>, <shoop.admin.utils.picotable.Column object at 0x7f655b4ca780>, <shoop.admin.utils.picotable.Column object at 0x7f655b4ca978>]
get_model()[source]
get_queryset()[source]
get_context_data(**kwargs)[source]
get_object_abstract(instance, item)[source]
shoop.admin.modules.users.views.password module
class shoop.admin.modules.users.views.password.PasswordChangeForm(changing_user, target_user, *args, **kwargs)[source]

Bases: django.forms.forms.Form

error_messages = {'password_incorrect': <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655b443208>, 'password_mismatch': <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655b4435f8>}
clean_password2()[source]
clean_old_password()[source]

Validates that the old_password field is correct.

save(commit=True)[source]
base_fields = OrderedDict([('old_password', <django.forms.fields.CharField object at 0x7f655b4430f0>), ('password1', <django.forms.fields.CharField object at 0x7f655b4439e8>), ('password2', <django.forms.fields.CharField object at 0x7f655b4b2860>)])
declared_fields = OrderedDict([('old_password', <django.forms.fields.CharField object at 0x7f655b4430f0>), ('password1', <django.forms.fields.CharField object at 0x7f655b4439e8>), ('password2', <django.forms.fields.CharField object at 0x7f655b4b2860>)])
media
class shoop.admin.modules.users.views.password.UserChangePasswordView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of PasswordChangeForm

template_name = 'shoop/admin/users/change_password.jinja'
model = 'auth.User'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_queryset()[source]
get_toolbar()[source]
get_form_kwargs()[source]
get_context_data(**kwargs)[source]
form_valid(form)[source]
get_success_url()[source]
class shoop.admin.modules.users.views.password.UserResetPasswordView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model = 'auth.User'
template_name = 'shoop/admin/users/reset_password.jinja'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_queryset()[source]
process_user(user)[source]
post(request, *args, **kwargs)[source]
get_success_url()[source]
shoop.admin.modules.users.views.permissions module
class shoop.admin.modules.users.views.permissions.PermissionChangeFormBase(changing_user, *args, **kwargs)[source]

Bases: django.forms.models.ModelForm

clean_old_password()[source]

Validates that the old_password field is correct.

clean()[source]
base_fields = OrderedDict([('old_password', <django.forms.fields.CharField object at 0x7f655b4b2be0>)])
declared_fields = OrderedDict([('old_password', <django.forms.fields.CharField object at 0x7f655b4b2be0>)])
media
class shoop.admin.modules.users.views.permissions.UserChangePermissionsView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/users/change_permissions.jinja'
model = 'auth.User'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_form_class()[source]
get_queryset()[source]
get_toolbar()[source]
get_form_kwargs()[source]
get_context_data(**kwargs)[source]
form_valid(form)[source]
get_success_url()[source]
Module contents
class shoop.admin.modules.users.views.UserListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655b443390>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cada0>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cabe0>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cad68>, <shoop.admin.utils.picotable.Column object at 0x7f655b4cab38>, <shoop.admin.utils.picotable.Column object at 0x7f655b4ca780>, <shoop.admin.utils.picotable.Column object at 0x7f655b4ca978>]
get_context_data(**kwargs)[source]
get_model()[source]
get_object_abstract(instance, item)[source]
get_queryset()[source]
model = 'auth.User'
class shoop.admin.modules.users.views.UserDetailView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'user'
dispatch(request, *args, **kwargs)[source]
fields = ('username', 'email', 'first_name', 'last_name')
get_form_class()[source]
get_initial()[source]
get_success_url()[source]
get_toolbar()[source]
post(request, *args, **kwargs)[source]
save_form(form)[source]
template_name = 'shoop/admin/users/detail.jinja'
class shoop.admin.modules.users.views.UserChangePasswordView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of PasswordChangeForm

form_valid(form)[source]
get_context_data(**kwargs)[source]
get_form_kwargs()[source]
get_queryset()[source]
get_success_url()[source]
get_toolbar()[source]
model = 'auth.User'
template_name = 'shoop/admin/users/change_password.jinja'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
class shoop.admin.modules.users.views.UserResetPasswordView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_queryset()[source]
get_success_url()[source]
model = 'auth.User'
post(request, *args, **kwargs)[source]
process_user(user)[source]
template_name = 'shoop/admin/users/reset_password.jinja'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
class shoop.admin.modules.users.views.UserChangePermissionsView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_valid(form)[source]
get_context_data(**kwargs)[source]
get_form_class()[source]
get_form_kwargs()[source]
get_queryset()[source]
get_success_url()[source]
get_toolbar()[source]
model = 'auth.User'
template_name = 'shoop/admin/users/change_permissions.jinja'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
Module contents
class shoop.admin.modules.users.UserModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_search_results(request, query)[source]
get_model_url(object, kind)[source]
Module contents
shoop.admin.template_helpers package
Submodules
shoop.admin.template_helpers.shoop_admin module

This module is installed as the shoop_admin template function namespace.

shoop.admin.template_helpers.shoop_admin.get_menu_entry_categories(context)[source]
shoop.admin.template_helpers.shoop_admin.get_front_url(context)[source]
shoop.admin.template_helpers.shoop_admin.get_config(context)[source]
shoop.admin.template_helpers.shoop_admin.model_url(model, kind='detail', default=None)[source]

Get a model URL of the given kind for a model (instance or class).

Parameters:
  • model (django.db.Model) – The model instance or class.
  • kind (str) – The URL kind to retrieve. See get_model_url.
  • default (str|None) – Default value to return if model URL retrieval fails. If None, the NoModelUrl exception is (re)raised.
Returns:

URL string.

Return type:

str

Module contents
shoop.admin.templatetags package
Submodules
shoop.admin.templatetags.shoop_admin module
class shoop.admin.templatetags.shoop_admin.Bootstrap3Namespace[source]

Bases: object

field(field, **kwargs)[source]
form(form, **kwargs)[source]
Module contents
shoop.admin.utils package
Submodules
shoop.admin.utils.bs3_renderers module
class shoop.admin.utils.bs3_renderers.AdminFieldRenderer(field, **kwargs)[source]

Bases: bootstrap3.renderers.FieldRenderer

get_label()[source]
add_class_attrs(*args, **kwargs)[source]
add_help_attrs(*args, **kwargs)[source]
shoop.admin.utils.forms module
shoop.admin.utils.forms.filter_form_field_choices(field, predicate, invert=False)[source]

Filter choices of a form field and its widget by predicate.

The predicate may be a callable of the signature (pair) -> bool or an iterable of allowable values.

Parameters:
  • field (django.forms.Field) – Form field.
  • predicate (function|Iterable) – Predicate
  • invert (bool) – Invert the semantics of the predicate, i.e. items matching it will be rejected.
Returns:

Nothing. The field is modified in-place.

shoop.admin.utils.forms.add_form_errors_as_messages(request, form)[source]

Add the form’s errors, if any, into the request as messages.

Parameters:
Returns:

Number of messages added. May be thousands, for a very unlucky form.

Return type:

int

shoop.admin.utils.forms.flatatt_filter(attrs)[source]
shoop.admin.utils.picotable module
shoop.admin.utils.picotable.maybe_callable(thing, context=None)[source]

If thing is callable, return it. If thing names a callable attribute of context, return it.

shoop.admin.utils.picotable.maybe_call(thing, context, args=None, kwargs=None)[source]

If thing is callable, call it with args and kwargs and return the value. If thing names a callable attribute of context, call it with args and kwargs and return the value. Otherwise return thing.

class shoop.admin.utils.picotable.Filter[source]

Bases: object

type = None
to_json(context)[source]
filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.ChoicesFilter(choices=None, filter_field=None)[source]

Bases: shoop.admin.utils.picotable.Filter

type = 'choices'
to_json(context)[source]
filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.RangeFilter(min=None, max=None, step=None, field_type=None, filter_field=None)[source]

Bases: shoop.admin.utils.picotable.Filter

Parameters:
  • filter_field (str|None) – Filter field (Django query expression). If None, column ID is used.
  • min – Minimum value.
  • max – Maximum value.
  • step – Step value. See the HTML5 documentation for semantics.
  • field_type (str|None) – Field type string. See the HTML5 documentation for semantics.
type = 'range'
to_json(context)[source]
filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.DateRangeFilter(*args, **kwargs)[source]

Bases: shoop.admin.utils.picotable.RangeFilter

filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.TextFilter(field_type=None, placeholder=None, operator='icontains', filter_field=None)[source]

Bases: shoop.admin.utils.picotable.Filter

Parameters:
  • filter_field (str|None) – Filter field (Django query expression). If None, column ID is used.
  • field_type (str|None) – Field type string. See the HTML5 documentation for semantics.
  • placeholder (str|None) – Field placeholder string.
  • operator (str) – Django operator for the queryset.
type = 'text'
to_json(context)[source]
filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.MultiFieldTextFilter(filter_fields, **kwargs)[source]

Bases: shoop.admin.utils.picotable.TextFilter

Parameters:
  • filter_field (list<str>) – List of Filter fields (Django query expression).
  • kwargs – Kwargs for TextFilter.
filter_queryset(queryset, column, value)[source]
class shoop.admin.utils.picotable.Column(id, title, **kwargs)[source]

Bases: object

to_json(context=None)[source]
sort_queryset(queryset, desc=False)[source]
filter_queryset(queryset, value)[source]
get_display_value(context, object)[source]
class shoop.admin.utils.picotable.Picotable(request, columns, queryset, context)[source]

Bases: object

process_queryset(query)[source]
get_data(query)[source]
process_item(object)[source]
get_verbose_name_plural()[source]
class shoop.admin.utils.picotable.PicotableViewMixin[source]

Bases: object

columns = []
picotable_class

alias of Picotable

template_name = 'shoop/admin/base_picotable.jinja'
process_picotable(query_json)[source]
get(request, *args, **kwargs)[source]
get_object_url(instance)[source]
get_object_abstract(instance, item)[source]

Get the object abstract lines (used for mobile layouts) for this object.

Supported keys in abstract line dicts are:

  • text (required)
  • title
  • class (CSS class name – header for instance)
  • raw (boolean; whether or not the text is raw HTML)
Parameters:
  • instance – The instance
  • item – The item dict so far. Useful for reusing precalculated values.
Returns:

Iterable of dicts to pass through to the picotable javascript

Return type:

Iterable[dict]

get_filter()[source]
shoop.admin.utils.search module
class shoop.admin.utils.search.FuzzyMatcher(query)[source]

Bases: object

test(text)[source]
shoop.admin.utils.search.split_query(query_string, minimum_part_length=3)[source]

Split a string into a set of non-empty words, none shorter than minimum_part_length characters.

Parameters:
  • query_string (str) – Query string
  • minimum_part_length (int) – Minimum part length
Returns:

Set of query parts

Return type:

set[str]

shoop.admin.utils.urls module
class shoop.admin.utils.urls.AdminRegexURLPattern(regex, callback, default_args=None, name=None, require_authentication=True, permissions=())[source]

Bases: django.core.urlresolvers.RegexURLPattern

wrap_with_permissions(view_func)[source]
callback
shoop.admin.utils.urls.admin_url(regex, view, kwargs=None, name=None, prefix='', require_authentication=True, permissions=())[source]
shoop.admin.utils.urls.get_edit_and_list_urls(url_prefix, view_template, name_template)[source]

Get a list of edit/new/list URLs for (presumably) an object type with standardized URLs and names.

Parameters:
  • url_prefix (str) – What to prefix the generated URLs with. E.g. "^taxes/tax"
  • view_template (str) – A template string for the dotted name of the view class. E.g. “shoop.admin.modules.taxes.views.Tax%sView”
  • name_template (str) – A template string for the URLnames. E.g. “tax.%s”
Returns:

List of URLs

Return type:

list[AdminRegexURLPattern]

exception shoop.admin.utils.urls.NoModelUrl[source]

Bases: ValueError

shoop.admin.utils.urls.get_model_url(object, kind='detail')[source]

Get a an admin object URL for the given object or object class by interrogating each admin module.

Raises NoModelUrl if lookup fails

Parameters:
  • object (class) – Model or object class.
  • kind (str) – URL kind. Currently “new”, “list”, “edit”, “detail”.
Returns:

Resolved URL.

Return type:

str

shoop.admin.utils.urls.derive_model_url(model_class, urlname_prefix, object, kind)[source]

Try to guess a model URL for the given object and kind.

An utility for people implementing get_model_url.

Parameters:
  • model_class (class) – The model class the object must be an instance or subclass of.
  • urlname_prefix (str) – URLname prefix. For instance, shoop_admin:product.
  • object (django.db.models.Model|class) – The model or model class as passed to get_model_url
  • kind (str) – URL kind as passed to get_model_url.
Returns:

Resolved URL or None.

Return type:

str|None

shoop.admin.utils.urls.manipulate_query_string(url, **qs)[source]
shoop.admin.utils.urls.get_model_front_url(request, object)[source]

Get a frontend URL for an object.

Parameters:
Returns:

URL or None

Return type:

str|None

shoop.admin.utils.views module
class shoop.admin.utils.views.CreateOrUpdateView(**kwargs)[source]

Bases: django.views.generic.edit.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

add_form_errors_as_messages = False
get_object(queryset=None)[source]
get_toolbar()[source]
get_context_data(**kwargs)[source]
get_save_form_id()[source]
get_return_url()[source]
get_new_url()[source]
get_success_url()[source]
get_form_kwargs()[source]
form_valid(form)[source]
save_form(form)[source]
form_invalid(form)[source]
shoop.admin.utils.views.add_create_or_change_message(request, instance, is_new)[source]
shoop.admin.utils.views.get_create_or_change_title(request, instance, name_field=None)[source]

Get a title suitable for an create-or-update view.

Parameters:
  • request (HttpRequest) – Request
  • instance (django.db.models.Model) – Model instance
  • name_field (str) – Which property to try to read the name from. If None, use str
Returns:

Title

Return type:

str

class shoop.admin.utils.views.PicotableListView(**kwargs)[source]

Bases: shoop.admin.utils.picotable.PicotableViewMixin, django.views.generic.list.ListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_toolbar()[source]
get_context_data(**kwargs)[source]
get_object_abstract(instance, item)[source]
Module contents
shoop.admin.views package
Submodules
shoop.admin.views.dashboard module
class shoop.admin.views.dashboard.DashboardView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/dashboard/dashboard.jinja'
get_context_data(**kwargs)[source]
get(request, *args, **kwargs)[source]
shoop.admin.views.menu module
class shoop.admin.views.menu.MenuView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/admin/base/_main_menu.jinja'
shoop.admin.views.search module
shoop.admin.views.search.get_search_results(request, query)[source]
class shoop.admin.views.search.SearchView(**kwargs)[source]

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get(request, *args, **kwargs)[source]
Module contents
Submodules
shoop.admin.base module
class shoop.admin.base.AdminModule[source]

Bases: object

name = 'Base'
breadcrumbs_menu_entry = None
get_urls()[source]
Return type:list[django.core.urlresolvers.RegexURLPattern]
get_menu_category_icons()[source]
Return type:dict[str,str]
get_menu_entries(request)[source]
Return type:list[shoop.admin.base.MenuEntry]
get_search_results(request, query)[source]
Return type:list[shoop.admin.base.SearchResult]
get_dashboard_blocks(request)[source]
Return type:list[shoop.admin.dashboard.DashboardBlock]
get_notifications(request)[source]
Return type:list[shoop.admin.base.Notification]
get_activity(request, cutoff)[source]
Parameters:
  • cutoff (datetime.datetime) – Cutoff datetime
  • request (django.http.request.HttpRequest) – Request
Returns:

list[shoop.admin.base.Activity]

get_model_url(object, kind)[source]

Retrieve an admin URL for the given object of the kind kind.

A falsy value must be returned if the module does not know how to reverse the given object.

Parameters:
  • object (django.db.models.Model) – A object instance (or object class).
  • kind (str) – URL kind. Currently “detail”, “list” or “new”.
Returns:

The reversed URL or none.

Return type:

str|None

class shoop.admin.base.Resolvable[source]

Bases: object

url

Resolve this object’s _url to an actual URL.

Returns:URL or no URL.
Return type:str|None
original_url
class shoop.admin.base.MenuEntry(text, url, icon=None, category=None, aliases=())[source]

Bases: shoop.admin.base.Resolvable

get_search_query_texts()[source]
class shoop.admin.base.SearchResult(text, url, icon=None, category=None, is_action=False, relevance=100)[source]

Bases: shoop.admin.base.Resolvable

to_json()[source]
class shoop.admin.base.Notification(text, title=None, url=None, kind='info', dismissal_url=None, datetime=None)[source]

Bases: shoop.admin.base.Resolvable

Parameters:
  • text (str) – The notification’s text.
  • title (str|None) – An optional title for the notification.
  • url (str|None) – The optional main URL for the notification.
  • kind (str) – The kind of the notification (see KINDS)
  • dismissal_url (str|None) – An optional dismissal URL for the notification. The admin framework will add a button that will cause an AJAX post into this URL.
  • datetime (datetime) – An optional date+time for this notification.
KINDS = ('info', 'success', 'warning', 'danger')
class shoop.admin.base.Activity(datetime, text, url=None)[source]

Bases: shoop.admin.base.Resolvable

shoop.admin.breadcrumbs module
class shoop.admin.breadcrumbs.Breadcrumbs(entries)[source]

Bases: object

classmethod infer(context)[source]

Infer breadcrumbs from the rendering context.

Parameters:context (jinja2.runtime.Context) – Jinja Context
Returns:Breadcrumbs object or None if things fail
Return type:Breadcrumbs|None
get_entries(request)[source]
shoop.admin.currencybound module
class shoop.admin.currencybound.CurrencyBound(currency=None, *args, **kwargs)[source]

Bases: object

Mixin for adding currency property defaulting currency of the first Shop.

The currency property is “lazy” so that database is not accessed on initialization, since this mixin will be used by some AdminModule classes and they will be initialized at import time by module_registry.register (which is called at import because admin.urls calls get_module_urls at import).

currency
shoop.admin.form_part module
class shoop.admin.form_part.TemplatedFormDef(name, form_class, template_name, required=True, kwargs=None)[source]

Bases: shoop.utils.form_group.FormDef

class shoop.admin.form_part.FormPart(request, object=None)[source]

Bases: object

priority = 0
get_form_defs()[source]
form_valid(form)[source]
class shoop.admin.form_part.FormPartsViewMixin[source]

Bases: object

fields = ()
request = None
form_part_class_provide_key = None
base_form_part_classes = ()
get_form_class()[source]
get_form_part_classes()[source]
get_form_parts(object)[source]
get_form(form_class=None)[source]
class shoop.admin.form_part.SaveFormPartsMixin[source]

Bases: object

request = None
object = None
save_form_parts(form)[source]
shoop.admin.menu module
shoop.admin.menu.get_menu_entry_categories(request)[source]
shoop.admin.module_registry module
shoop.admin.module_registry.register(module_class)[source]
shoop.admin.module_registry.discover()[source]
shoop.admin.module_registry.get_modules()[source]
Return type:list[shoop.admin.base.AdminModule]
shoop.admin.module_registry.get_module_urls()[source]
shoop.admin.module_registry.replace_modules(new_module_classes)[source]

Context manager to temporarily replace all modules with something else.

Test utility, mostly.

>>> def some_test():
...     with replace_modules(["foo.bar:QuuxModule"]):
...         pass # do stuff
Parameters:new_module_classes – Iterable of module classes, like you’d pass to register
shoop.admin.toolbar module
class shoop.admin.toolbar.BaseActionButton(text='', icon=None, disable_reason=None, tooltip=None, extra_css_class='btn-default')[source]

Bases: object

Parameters:
  • text – The actual text for the button.
  • icon – Icon CSS class string
  • disable_reason (str|None) – The reason for this button to be disabled. It’s considered good UX to have an user-visible reason for disabled actions; thus the only way to disable an action is to set the reason. See http://stackoverflow.com/a/372503/51685.
  • tooltip (str|None) – Tooltip string, if any. May be replaced by the disable reason.
  • extra_css_class (str) – Extra CSS class(es)
base_css_classes = ('btn',)
render(request)[source]

Yield HTML bits for this object. :type request: HttpRequest :rtype: Iterable[str]

render_label()[source]
get_computed_class()[source]
class shoop.admin.toolbar.URLActionButton(url, **kwargs)[source]

Bases: shoop.admin.toolbar.BaseActionButton

An action button that renders as a link leading to url.

Parameters:url (str) – The URL to navigate to. For convenience, if this contains no slashes, reverse is automatically called on it.
render(request)[source]
class shoop.admin.toolbar.NewActionButton(url, **kwargs)[source]

Bases: shoop.admin.toolbar.URLActionButton

An URL button with sane “new” visual semantics

classmethod for_model(model, **kwargs)[source]

Generate a NewActionButton for a model, auto-wiring the URL.

Parameters:model – Model class
Return type:shoop.admin.toolbar.NewActionButton|None
class shoop.admin.toolbar.JavaScriptActionButton(onclick, **kwargs)[source]

Bases: shoop.admin.toolbar.BaseActionButton

An action button that uses onclick for action dispatch.

render(request)[source]
class shoop.admin.toolbar.PostActionButton(post_url=None, name=None, value=None, form_id=None, confirm=None, **kwargs)[source]

Bases: shoop.admin.toolbar.BaseActionButton

An action button that renders as a button POSTing a form containing name`=`value to post_url.

render(request)[source]
class shoop.admin.toolbar.DropdownActionButton(items, split_button=None, **kwargs)[source]

Bases: shoop.admin.toolbar.BaseActionButton

An action button with a chevron button to open a dropdown menu.

base_css_classes = ('btn', 'dropdown-toggle')
render_dropdown(request)[source]
render(request)[source]
class shoop.admin.toolbar.DropdownItem(url='#', onclick=None, **kwargs)[source]

Bases: shoop.admin.toolbar.BaseActionButton

An item to be shown in a DropdownActionButton.

base_css_classes = ()
render(request)[source]
class shoop.admin.toolbar.DropdownDivider(text='', icon=None, disable_reason=None, tooltip=None, extra_css_class='btn-default')[source]

Bases: shoop.admin.toolbar.BaseActionButton

A Divider for DropdownActionButtons.

Parameters:
  • text – The actual text for the button.
  • icon – Icon CSS class string
  • disable_reason (str|None) – The reason for this button to be disabled. It’s considered good UX to have an user-visible reason for disabled actions; thus the only way to disable an action is to set the reason. See http://stackoverflow.com/a/372503/51685.
  • tooltip (str|None) – Tooltip string, if any. May be replaced by the disable reason.
  • extra_css_class (str) – Extra CSS class(es)
base_css_classes = ()
render(request)[source]
class shoop.admin.toolbar.DropdownHeader(text='', icon=None, disable_reason=None, tooltip=None, extra_css_class='btn-default')[source]

Bases: shoop.admin.toolbar.BaseActionButton

Header for DropdownActionButtons.

Parameters:
  • text – The actual text for the button.
  • icon – Icon CSS class string
  • disable_reason (str|None) – The reason for this button to be disabled. It’s considered good UX to have an user-visible reason for disabled actions; thus the only way to disable an action is to set the reason. See http://stackoverflow.com/a/372503/51685.
  • tooltip (str|None) – Tooltip string, if any. May be replaced by the disable reason.
  • extra_css_class (str) – Extra CSS class(es)
base_css_classes = ()
render(request)[source]
class shoop.admin.toolbar.ButtonGroup[source]

Bases: list

render(request)[source]
class shoop.admin.toolbar.Toolbar[source]

Bases: list

render(request)[source]
render_to_string(request)[source]
shoop.admin.toolbar.try_reverse(viewname, **kwargs)[source]
shoop.admin.toolbar.get_discard_button(discard_url)[source]
shoop.admin.toolbar.get_default_edit_toolbar(view_object, save_form_id, discard_url=None, delete_url=None, with_split_save=True, toolbar=None)[source]

Get a toolbar with buttons used for object editing.

Parameters:
  • view_object (django.views.generic.UpdateView) – The class-based-view object requiring the toolbar
  • save_form_id (str) – The DOM ID to target for the save button
  • discard_url (str|None) – The URL/route name for the Discard button. Falsy values default to the request URL.
  • delete_url (str|None) – The URL/route name for the Delete button. If this is not set, the delete button is not shown.
  • with_split_save (bool) – Use split delete button with “Save and Exit” etc.?
  • toolbar (Toolbar) – The toolbar to augment. If None, a new one is created.
Returns:

Toolbar

Return type:

Toolbar

shoop.admin.urls module
shoop.admin.urls.login(request, **kwargs)[source]
shoop.admin.urls.get_urls()[source]
Module contents
class shoop.admin.ShoopAdminAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.admin'
verbose_name = 'Shoop Admin'
label = 'shoop_admin'
required_installed_apps = ['bootstrap3']
provides = {'admin_module': ['shoop.admin.modules.system:SystemModule', 'shoop.admin.modules.products:ProductModule', 'shoop.admin.modules.product_types:ProductTypeModule', 'shoop.admin.modules.media:MediaModule', 'shoop.admin.modules.orders:OrderModule', 'shoop.admin.modules.taxes:TaxModule', 'shoop.admin.modules.categories:CategoryModule', 'shoop.admin.modules.contacts:ContactModule', 'shoop.admin.modules.contact_groups:ContactGroupModule', 'shoop.admin.modules.users:UserModule', 'shoop.admin.modules.methods:MethodModule', 'shoop.admin.modules.attributes:AttributeModule', 'shoop.admin.modules.sales_units:SalesUnitModule', 'shoop.admin.modules.shops:ShopModule', 'shoop.admin.modules.demo:DemoModule', 'shoop.admin.modules.manufacturers:ManufacturerModule', 'shoop.admin.modules.suppliers:SupplierModule']}
ready()[source]
shoop.api package
Submodules
shoop.api.encoders module
class shoop.api.encoders.ExtJSONEncoder(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: rest_framework.utils.encoders.JSONEncoder

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an OverflowError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (‘, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

default(obj)[source]
shoop.api.encoders.apply_monkeypatch()[source]
shoop.api.factories module
shoop.api.factories.serializer_factory(model, serializer_class=None, attrs=None, meta=None)[source]
shoop.api.factories.viewset_factory(model, viewset_class=<class 'rest_framework.viewsets.ModelViewSet'>, **attrs)[source]
shoop.api.urls module
class shoop.api.urls.AutoRouter(trailing_slash=True)[source]

Bases: rest_framework.routers.DefaultRouter

populate()[source]
Module contents
class shoop.api.ShoopApiAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.api'
verbose_name = 'Shoop API'
label = 'shoop_api'
required_installed_apps = ('rest_framework',)
ready()[source]
shoop.apps package
Submodules
shoop.apps.provides module

This module contains the API to deal with the Provides system.

The Provides system is Shoop’s mechanism for discovering and loading components, both first-party and third-party.

See also

See The Provides system for further information about the Provides system.

shoop.apps.provides.clear_provides_cache()[source]
shoop.apps.provides.get_provide_specs_and_objects(category)[source]

Get a mapping of provide specs (“x.y.z:Q”) to their loaded objects (<class Q>).

Parameters:category (str) – Category to load objects for
Returns:Dict of spec -> object
Return type:dict[str, object]
shoop.apps.provides.get_provide_objects(category)[source]

Get an iterable of provide objects for the given category.

Parameters:category (str) – Category to load objects for
Returns:Iterable of objects
Return type:Iterable[object]
shoop.apps.provides.get_identifier_to_spec_map(category)[source]
shoop.apps.provides.get_identifier_to_object_map(category)[source]
shoop.apps.provides.override_provides(category, spec_list)[source]

Context manager to override provides for a given category.

Useful for testing.

Parameters:
  • category (str) – Category name.
  • spec_list (list[str]) – List of specs.
shoop.apps.provides.load_module(setting_name, provide_category)[source]

Load a module from a module setting.

The value of the setting must be a module identifier for the given provide category.

Parameters:
  • setting_name (str) – The setting name for the identifier
  • provide_category (str) – The provide category for the identifier lookup (e.g. tax_module)
Returns:

An object.

Return type:

object

shoop.apps.settings module
shoop.apps.settings.collect_settings_from_app(app_config)[source]
shoop.apps.settings.collect_settings(app_name, settings_module)[source]
shoop.apps.settings.get_known_settings()[source]

Get all settings known to Shoop.

Return type:Iterable[Setting]
class shoop.apps.settings.Setting(name, default, app_name, module)[source]

Bases: object

shoop.apps.settings.validate_templates_configuration()[source]

Validate the TEMPLATES configuration in the Django settings.

Shoop’s admin and default frontend require some Django-Jinja configuration, so let’s make sure clients configure their projects correctly.

Raises:Raises ImproperlyConfigured if the configuration does not seem valid.
Returns:
Return type:
Module contents
Shoop Application API

Every Shoop Application should define an app config class derived from shoop.apps.AppConfig.

Settings

To define settings for a Shoop Application, add a settings.py file to your app and define each setting as a module level variable with uppercase name. The values of these setting variables will be used as the default values for the settings. To document a setting, add a special comment block using ‘#: ‘ prefixed lines just before the setting assignment line.

Default values can then be changed normally by defining the changed value in your Django settings module. To read a value of a setting use the django.conf.settings interface.

For example, if a fancy app lives in a Python package named fancyapp, its settings will be in module fancyapp.settings and if it contains something like this

#: Number of donuts to use
#:
#: Must be less than 42.
FANCYAPP_NUMBER_OF_DONUTS = 3

then this would define a setting FANCYAPP_NUMBER_OF_DONUTS with a default value of 3.

See also source code of shoop.core.settings.

Naming Settings

Applications in Shoop Base distribution should use the following rules for naming their settings.

  1. Each setting should be prefixed with the string SHOOP_
  2. Boolean toggle settings should have a verb in imperative mood as part of the name, e.g. SHOOP_ALLOW_ANONYMOUS_ORDERS, SHOOP_ENABLE_ATTRIBUTES or SHOOP_ENABLE_MULTIPLE_SHOPS.
  3. Setting that is used to locate a replaceable module should have suffix _SPEC or _SPECS (if the setting is a list or mapping of those), e.g. SHOOP_PRICING_MODULE_SPEC.
  4. Setting names do NOT have to be prefixed with the application name. For example, SHOOP_BASKET_VIEW_SPEC which is not prefixed with SHOOP_FRONT even though it is from shoop.front application.
  5. Setting names should be unique; if two applications define a setting with a same name, they cannot be enabled in the same installation.

Warning

When you have a settings file your_app/settings.py, do not import Django’s settings in your_app/__init__.py with

from django.conf import settings

since that will make your_app.settings ambiguous. It may point to django.conf.settings when your_app.settings is not yet imported, or when it is imported, it will point to module defined by your_app/settings.py.

class shoop.apps.AppConfig(*args, **kwargs)[source]

Bases: django.apps.config.AppConfig

default_settings_module = '.settings'

Name of the settings module for this app

required_installed_apps = ()

Apps that are required to be in INSTALLED_APPS for this app

This may also be a dict of the form {app_name: reason} where the reason will then be listed in the ImproperlyConfigured exception.

provides = {}

See The Provides system for details about the provides variable.

get_default_settings_module()[source]

Get default settings module.

Returns:the settings module
Raises:ImportError if no such module exists
shoop.apps.get_known_settings()[source]

Get all settings known to Shoop.

Return type:Iterable[Setting]
shoop.core package
Subpackages
shoop.core.api package
Submodules
shoop.core.api.orders module
class shoop.core.api.orders.OrderLineSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

model

alias of OrderLine

class shoop.core.api.orders.AddressSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

model

alias of MutableAddress

class shoop.core.api.orders.OrderSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

get_fields()[source]
create(validated_data)[source]
class Meta[source]

Bases: object

model

alias of Order

class shoop.core.api.orders.OrderViewSet(**kwargs)[source]

Bases: rest_framework.viewsets.ModelViewSet

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

serializer_class

alias of OrderSerializer

queryset
suffix = None
shoop.core.api.products module
class shoop.core.api.products.ShopProductSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

model

alias of ShopProduct

extra_kwargs = {'payment_methods': {'required': False}, 'categories': {'required': False}, 'visibility_groups': {'required': False}, 'suppliers': {'required': False}, 'shipping_methods': {'required': False}}
class shoop.core.api.products.ProductSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: parler_rest.serializers.TranslatableModelSerializer

class Meta[source]

Bases: object

model

alias of Product

class shoop.core.api.products.ProductViewSet(**kwargs)[source]

Bases: rest_framework.viewsets.ModelViewSet

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

queryset = []
serializer_class

alias of ProductSerializer

get_queryset()[source]
suffix = None
class shoop.core.api.products.ShopProductViewSet(**kwargs)[source]

Bases: rest_framework.viewsets.ModelViewSet

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

queryset = []
serializer_class

alias of ShopProductSerializer

get_queryset()[source]
suffix = None
Module contents
shoop.core.api.populate_core_api(router)[source]
Parameters:router (rest_framework.routers.DefaultRouter) – Router
shoop.core.cache package
Submodules
shoop.core.cache.impl module
shoop.core.cache.impl.get_cache_duration(cache_key)[source]

Determine a cache duration for the given cache key.

Parameters:cache_key (str) – Cache key string
Returns:Timeout seconds
Return type:int
class shoop.core.cache.impl.VersionedCache(using)[source]

Bases: object

Parameters:using (str) – Cache alias
bump_version(cache_key)[source]

Bump up the cache version for the given cache key/namespace.

Parameters:cache_key (str) – Cache key or namespace
get_version(cache_key)[source]

Get the cache version (or None) for the given cache key/namespace.

The cache version is stored in thread-local storage for the current request, so unless bumped in-request, all gets within a single request should get coherently versioned data from the cache.

Parameters:cache_key (str) – Cache key or namespace
Returns:Version ID or none
Return type:str|None
set(key, value, timeout=None, version=None)[source]

Set the value for key key in the cache.

Unlike django.core.caches[using].set(), this also derives timeout and versioning information from the key (and cached version data) if the key begins with a colon-separated namespace, such as foo:bar.

Parameters:
  • key (str) – Cache key
  • value (object) – Value to cache
  • timeout (int|None) – Timeout seconds or None (for auto-determination)
  • version (str|None) – Version string or None (for auto-determination)
  • using (str) – Cache alias
get(key, version=None, default=None)[source]

Get the value for key key in the cache.

Unlike django.core.caches[using].get(), versioning information can be auto-derived from the key (and cached version data) if the key begins with a colon-separated namespace, such as foo:bar.

Parameters:
  • key (str) – Cache key
  • version (str|None) – Version string or None (for auto-determination)
  • default (object) – Default value, if the key is not found
  • using (str) – Cache alias
Returns:

cached value

Return type:

object

clear()[source]
Module contents

Utilities for versioned caching and automatic timeout determination.

Versioning works by way of namespaces. Namespaces are the first colon-separated part of cache keys.

For instance, the cache keys price:10, price:20, and price all belong to the price namespace and can be invalidated with one bump_version("price") call.

The versions themselves are stored within the cache, within the _version namespace. (As an implementation detail, this allows one to invalidate _all_ versioned keys by bumping the version of _version. Very meta!)

class shoop.core.cache.VersionedCache(using)[source]

Bases: object

Parameters:using (str) – Cache alias
bump_version(cache_key)[source]

Bump up the cache version for the given cache key/namespace.

Parameters:cache_key (str) – Cache key or namespace
clear()[source]
get(key, version=None, default=None)[source]

Get the value for key key in the cache.

Unlike django.core.caches[using].get(), versioning information can be auto-derived from the key (and cached version data) if the key begins with a colon-separated namespace, such as foo:bar.

Parameters:
  • key (str) – Cache key
  • version (str|None) – Version string or None (for auto-determination)
  • default (object) – Default value, if the key is not found
  • using (str) – Cache alias
Returns:

cached value

Return type:

object

get_version(cache_key)[source]

Get the cache version (or None) for the given cache key/namespace.

The cache version is stored in thread-local storage for the current request, so unless bumped in-request, all gets within a single request should get coherently versioned data from the cache.

Parameters:cache_key (str) – Cache key or namespace
Returns:Version ID or none
Return type:str|None
set(key, value, timeout=None, version=None)[source]

Set the value for key key in the cache.

Unlike django.core.caches[using].set(), this also derives timeout and versioning information from the key (and cached version data) if the key begins with a colon-separated namespace, such as foo:bar.

Parameters:
  • key (str) – Cache key
  • value (object) – Value to cache
  • timeout (int|None) – Timeout seconds or None (for auto-determination)
  • version (str|None) – Version string or None (for auto-determination)
  • using (str) – Cache alias
shoop.core.defaults package
Submodules
shoop.core.defaults.order_statuses module
shoop.core.defaults.order_statuses.create_default_order_statuses()[source]
Module contents
shoop.core.fields package
Submodules
shoop.core.fields.tagged_json module

“Tagged JSON” encoder/decoder.

Objects that are normally not unambiguously representable via JSON are encoded into special objects of the form {tag: val}; the encoding and decoding process can be customized however necessary.

shoop.core.fields.tagged_json.isoformat(obj)[source]
shoop.core.fields.tagged_json.encode_enum(enum_val)[source]
shoop.core.fields.tagged_json.decode_enum(val)[source]
class shoop.core.fields.tagged_json.TagRegistry[source]

Bases: object

register(tag, classes, encoder=<class 'str'>, decoder=None)[source]
encode(obj, default)[source]
decode(obj)[source]
shoop.core.fields.tagged_json.tag_registry = <shoop.core.fields.tagged_json.TagRegistry object>

The default tag registry.

class shoop.core.fields.tagged_json.TaggedJSONEncoder(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: jsonfield.encoder.JSONEncoder

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an OverflowError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (‘, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

registry = <shoop.core.fields.tagged_json.TagRegistry object>
default(obj)[source]
Module contents
class shoop.core.fields.InternalIdentifierField(**kwargs)[source]

Bases: django.db.models.fields.CharField

get_prep_value(value)[source]
deconstruct()[source]
class shoop.core.fields.CurrencyField(**kwargs)[source]

Bases: django.db.models.fields.CharField

class shoop.core.fields.MoneyValueField(**kwargs)[source]

Bases: django.db.models.fields.DecimalField

class shoop.core.fields.QuantityField(**kwargs)[source]

Bases: django.db.models.fields.DecimalField

class shoop.core.fields.MeasurementField(unit, **kwargs)[source]

Bases: django.db.models.fields.DecimalField

KNOWN_UNITS = ('mm', 'm', 'kg', 'g', 'm3')
deconstruct()[source]
class shoop.core.fields.LanguageField(*args, **kwargs)[source]

Bases: django.db.models.fields.CharField

LANGUAGE_CODES = {'frr', 'mh', 'qug', 'del', 'av', 'tiv', 'vot', 'yue', 'it', 'osa', 'hsn', 'chg', 'tkr', 'lus', 'su', 'fo', 'io', 'ms', 'sco', 'fro', 'hif', 'mt', 'koi', 'sux', 'ca', 'mul', 'seh', 'krj', 'sli', 'vro', 'nia', 'bfd', 'tlh', 'en_US', 'km', 'en_GB', 'kn', 'bal', 'ay', 'suk', 'id', 'om', 'ceb', 'ho', 'eka', 'zza', 'pl', 'lrc', 'udm', 'pt', 'arc', 'rue', 'kaw', 'chr', 'got', 'zxx', 'srr', 'arw', 'nym', 'gwi', 'jgo', 'sq', 'gor', 'vun', 'vai', 'mni', 'fa', 'bej', 'sr', 'mrj', 'frm', 'ne', 'sma', 'dv', 'mak', 'mwv', 'bra', 'dzg', 'jmc', 'lzh', 'ckb', 'za', 'pdt', 'awa', 'tr', 'en_CA', 'ps', 'cv', 'ku', 'pap', 'sd', 'agq', 'ttt', 'ady', 'mde', 'lah', 'hit', 'fon', 'hsb', 'sba', 'srn', 'njo', 'byn', 'ka', 'as', 'mag', 'sah', 'tsd', 'et', 'ain', 'vi', 'kaa', 'mos', 'ak', 'dua', 'chn', 'mg', 'non', 'dtp', 'lo', 'kab', 'rug', 'zu', 'swb', 'pal', 'sdc', 'br', 'ksh', 'ewo', 'shi', 'fil', 'mk', 'oc', 'hak', 'szl', 'ty', 'ce', 'lzz', 'th', 'pt_BR', 'kam', 'hil', 'goh', 'avk', 'bez', 'es', 'tem', 'tpi', 'ml', 'egl', 'sms', 'lv', 'wa', 'kbl', 'sdh', 'egy', 'es_419', 'my', 'ary', 'tw', 'lt', 'bjn', 'tog', 'ext', 'lua', 'tn', 'krl', 'uz', 'tvl', 'pa', 'gl', 'hup', 'cho', 'kk', 'dyo', 'ban', 'luy', 'den', 'vmf', 'mnc', 'arz', 'ro', 'sh', 'kln', 'peo', 'sat', 'khw', 'saz', 'cad', 'jbo', 'ebu', 'asa', 'ale', 'xmf', 'ksf', 'tru', 'xog', 'guc', 'pau', 'vep', 'trv', 'kho', 'mdr', 'gba', 'hi', 'cgg', 'yo', 'kgp', 'kum', 'az', 'lez', 'chp', 'ny', 'tt', 'ter', 'oj', 'mn', 'dgr', 'ang', 'min', 'syc', 'fit', 'bss', 'ig', 'nds', 'nl_BE', 'jpr', 'kru', 'co', 'tum', 'ar_001', 'ky', 'pi', 'sad', 'chk', 'maf', 'en_AU', 'nyo', 'an', 'eu', 'din', 'kde', 'cr', 'hy', 'uk', 'da', 'ota', 'bbj', 'aln', 'kea', 'iu', 'kr', 'ase', 'ast', 'cop', 'pag', 'sly', 'kcg', 'new', 'mic', 'arq', 'ff', 'myv', 'gsw', 'es_ES', 'ti', 'mye', 'wal', 'nap', 'dsb', 'gv', 'zap', 'bs', 'hai', 'kl', 'gu', 'elx', 'sei', 'bar', 'aeb', 'nov', 'gan', 'akz', 'he', 'tsi', 'ssy', 'ik', 'tli', 'ko', 'ch', 'fan', 'frs', 'tkl', 'akk', 'inh', 'kw', 'lu', 'ltg', 'shu', 'pro', 'gon', 'lam', 'kpe', 'tcy', 'mr', 'lag', 'bin', 'gag', 'nb', 'man', 'arp', 'izh', 'fy', 'twq', 'ba', 'yao', 'root', 'nyn', 'bua', 'kaj', 'mus', 'car', 'dyu', 'de_AT', 'pcd', 'lun', 'to', 'ug', 'fj', 'tyv', 'men', 'wae', 'kmb', 'be', 'zh_Hans', 'wo', 'is', 'gaa', 'bqi', 'dz', 'luo', 'quc', 'bho', 'mwl', 'rtm', 'grb', 'smn', 'mua', 'guz', 'kg', 'ks', 'sga', 'sm', 'yi', 'sw', 'khq', 'dum', 'tg', 'kj', 'or', 'tk', 'ki', 'phn', 'ur', 'rof', 'li', 'de_CH', 'nus', 'war', 'ybb', 'kbd', 'sgs', 'sa', 'qu', 'nl', 'mgh', 'dak', 'alt', 'el', 'ga', 'kos', 'mgo', 'bn', 'lmo', 'brx', 'ken', 'zh_Hant', 'bo', 'sg', 'frp', 'zbl', 'syr', 'cs', 'bla', 'mer', 'ii', 'brh', 'sn', 'kac', 'ss', 'bik', 'bgn', 'bfq', 'fr_CH', 'sbp', 'te', 'was', 'os', 'fat', 'efi', 'gd', 'moh', 'und', 'gur', 'rom', 'pam', 'yrl', 'rw', 'jut', 'gmh', 'bug', 'vo', 'lkt', 'cps', 'pon', 'cy', 'am', 'fa_AF', 'bm', 'wbp', 'ha', 'vls', 'grc', 'dje', 'nmg', 'stq', 'fr', 'pdc', 'haw', 'mad', 'umb', 'sam', 'rn', 'loz', 'dar', 'sk', 'so', 'hu', 'ee', 'nn', 'liv', 'xal', 'jv', 'rap', 'tl', 'xh', 'mfe', 'yav', 'sus', 'zh', 'ta', 'vec', 'kok', 'cay', 'mdf', 'ace', 'gbz', 'chb', 'kiu', 've', 'sog', 'lij', 'hr', 'fur', 'bem', 'mi', 'zgh', 'bg', 'sid', 'doi', 'nso', 'ses', 'kut', 'mga', 'pt_PT', 'nan', 'cch', 'ilo', 'ia', 'nzi', 'raj', 'dav', 'ro_MD', 'gn', 'nog', 'zea', 'nqo', 'mzn', 'mas', 'uga', 'nd', 'ar', 'sel', 'smj', 'gez', 'scn', 'gay', 'bew', 'ksb', 'krc', 'se', 'bas', 'pfl', 'kkj', 'enm', 'csb', 'bkm', 'cu', 'ibb', 'snk', 'lfn', 'nds_NL', 'swc', 'see', 'tmh', 'nr', 'prg', 'eo', 'hz', 'de', 'si', 'hmn', 'no', 'tzm', 'bum', 'pms', 'glk', 'ts', 'zun', 'shn', 'jam', 'bpy', 'afh', 'sas', 'anp', 'bax', 'la', 'na', 'en', 'kha', 'fi', 'lb', 'ht', 'naq', 'fr_CA', 'chy', 'kv', 'bi', 'af', 'mwr', 'gom', 'sl', 'tly', 'rwk', 'lui', 'iba', 'saq', 'ng', 'aa', 'niu', 'rm', 'rup', 'yap', 'bbc', 'gil', 'sc', 'chm', 'crh', 'ln', 'kri', 'lg', 'zen', 'frc', 'lol', 'kfo', 'tet', 'rif', 'tig', 'ach', 'sv', 'ja', 'lad', 'st', 'es_MX', 'nnh', 'wuu', 'arn', 'ae', 'pnt', 'esu', 'rgn', 'jrb', 'byv', 'mai', 'nv', 'ab', 'aro', 'ada', 'teo', 'ru', 'ie', 'rar', 'nwc'}
get_choices(include_blank=True, blank_choice=[('', '---------')])[source]
class shoop.core.fields.UnsavedForeignKey(to, to_field=None, rel_class=<class 'django.db.models.fields.related.ManyToOneRel'>, db_constraint=True, **kwargs)[source]

Bases: django.db.models.fields.related.ForeignKey

allow_unsaved_instance_assignment = True
class shoop.core.fields.TaggedJSONField(*args, **kwargs)[source]

Bases: jsonfield.fields.JSONField

contribute_to_class(cls, name)
shoop.core.management package
Subpackages
shoop.core.management.commands package
Submodules
shoop.core.management.commands.makemessages module

Patched version of Django’s Makemessages that works with Jinja2.

Works by monkey patching django.utils.translation.trans_real.templatize with our version.

class shoop.core.management.commands.makemessages.Command(stdout=None, stderr=None, no_color=False)[source]

Bases: django.core.management.commands.makemessages.Command

add_arguments(parser)[source]
handle(*args, **options)[source]
build_potfiles()[source]

Build PO Template files and return paths to them.

Extends base classes version of this method by adding the “Remove POT-Creation-Date” feature.

write_po_file(potfile, locale)[source]

Writo PO file of given locale to disk.

Extends base classes version of this method by adding a feature to not change those PO files at all that have only the “POT-Creation-Date” header changed.

shoop.core.management.commands.makemessages.jinja_messages_to_python(src, origin=None)[source]

Convert Jinja2 file to Python preserving only messages.

shoop.core.management.commands.makemessages.extract_jinja(contents, origin=None)[source]
shoop.core.management.commands.shoop_init module
shoop.core.management.commands.shoop_init.schema(model, identifier, **info)[source]
class shoop.core.management.commands.shoop_init.Initializer[source]

Bases: object

schemata = [{'info': {'name': 'Default Shop', 'status': <ShopStatus.ENABLED: 1>}, 'model': <class 'shoop.core.models.Shop'>, 'identifier': 'default'}, {'info': {'name': 'Standard Product'}, 'model': <class 'shoop.core.models.ProductType'>, 'identifier': 'default'}, {'info': {'name': 'Download Product'}, 'model': <class 'shoop.core.models.ProductType'>, 'identifier': 'download'}, {'info': {'name': 'Default Tax Class'}, 'model': <class 'shoop.core.models.TaxClass'>, 'identifier': 'default'}, {'info': {'tax_class': <class 'shoop.core.models.TaxClass'>, 'name': 'Default Payment Method'}, 'model': <class 'shoop.core.models.PaymentMethod'>, 'identifier': 'default'}, {'info': {'tax_class': <class 'shoop.core.models.TaxClass'>, 'name': 'Default Shipping Method'}, 'model': <class 'shoop.core.models.ShippingMethod'>, 'identifier': 'default'}, {'info': {'name': 'Default Supplier'}, 'model': <class 'shoop.core.models.Supplier'>, 'identifier': 'default'}, {'info': {'name': 'Pieces'}, 'model': <class 'shoop.core.models.SalesUnit'>, 'identifier': 'pcs'}, {'info': {'name': 'Default Category'}, 'model': <class 'shoop.core.models.Category'>, 'identifier': 'default'}, {'info': {'name': 'Retail Customers'}, 'model': <class 'shoop.core.models.CustomerTaxGroup'>, 'identifier': 'default_person_customers'}, {'info': {'name': 'Company Customers'}, 'model': <class 'shoop.core.models.CustomerTaxGroup'>, 'identifier': 'default_company_customers'}]
process_schema(schema)[source]
run()[source]
class shoop.core.management.commands.shoop_init.Command(stdout=None, stderr=None, no_color=False)[source]

Bases: django.core.management.base.BaseCommand

leave_locale_alone = True
handle(*args, **options)[source]
shoop.core.management.commands.shoop_makemessages module

Makemessages helper for Shoop projects.

Runs Django’s makemessages for django and djangojs domains with sane defaults for Shoop projects (ignores and extensions).

class shoop.core.management.commands.shoop_makemessages.Command(stdout=None, stderr=None, no_color=False)[source]

Bases: shoop.core.management.commands.makemessages.Command

help = "\nMakemessages helper for Shoop projects.\n\nRuns Django's makemessages for django and djangojs domains with sane\ndefaults for Shoop projects (ignores and extensions).\n"
add_arguments(parser)[source]
handle(*args, **options)[source]
shoop.core.management.commands.shoop_show_settings module

Show known Shoop settings and their values.

class shoop.core.management.commands.shoop_show_settings.Command(stdout=None, stderr=None, no_color=False)[source]

Bases: django.core.management.base.BaseCommand

help = 'Show known Shoop settings and their values.'
option_list = (<Option at 0x7f655942b6a0: --only-changed>,)
handle(*args, **options)[source]
Module contents
Module contents
shoop.core.methods package
Submodules
shoop.core.methods.base module
class shoop.core.methods.base.BaseMethodModule(method, options)[source]

Bases: object

Base method module implementation.

checkout_phase_class = None
identifier = None
name = None
admin_detail_view_class = None
option_fields = [('price', <django.forms.fields.DecimalField object at 0x7f65593e3ac8>), ('price_waiver_product_minimum', <django.forms.fields.DecimalField object at 0x7f65593e39b0>)]
get_options()[source]
get_validation_errors(source, **kwargs)[source]

Return an iterable of human-readable errors (either Django’s ValidationError`s or just plain old strings) if there are any errors that would prevent using this method with a given `source.

This (instead of raising an error) broadly follows the Notification pattern. http://martinfowler.com/eaaDev/Notification.html

Parameters:
  • source – source object
  • kwargs – Other kwargs for future expansion
Returns:

Iterable of errors

Return type:

Iterable[str]

get_effective_price_info(source, **kwargs)[source]

Get price of this method for given OrderSource.

Parameters:
Return type:

shoop.core.pricing.PriceInfo

get_effective_name(source, **kwargs)[source]

Return the effective name for this method. Useful to add shipping mode (“letter”, “parcel”) for instance.

Parameters:
Returns:

name

Return type:

unicode

get_source_lines(source)[source]
class shoop.core.methods.base.BaseShippingMethodModule(method, options)[source]

Bases: shoop.core.methods.base.BaseMethodModule

Base shipping method module implementation.

no_lower_limit_text = <django.utils.functional.lazy.<locals>.__proxy__ object>
option_fields = [('price', <django.forms.fields.DecimalField object at 0x7f65593e3ac8>), ('price_waiver_product_minimum', <django.forms.fields.DecimalField object at 0x7f65593e39b0>), ('min_weight', <django.forms.fields.DecimalField object at 0x7f655942b240>), ('max_weight', <django.forms.fields.DecimalField object at 0x7f655942b2e8>)]
get_validation_errors(source, **kwargs)[source]
class shoop.core.methods.base.BasePaymentMethodModule(method, options)[source]

Bases: shoop.core.methods.base.BaseMethodModule

Base payment method module implementation.

get_payment_process_response(order, urls)[source]
process_payment_return_request(order, request)[source]
shoop.core.methods.default module
class shoop.core.methods.default.DefaultShippingMethodModule(method, options)[source]

Bases: shoop.core.methods.base.BaseShippingMethodModule

identifier = 'default_shipping'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
class shoop.core.methods.default.DefaultPaymentMethodModule(method, options)[source]

Bases: shoop.core.methods.base.BasePaymentMethodModule

identifier = 'default_payment'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
Module contents
shoop.core.models package
Module contents
class shoop.core.models.AnonymousContact(id, polymorphic_ctype, created_on, identifier, is_active, default_shipping_address, default_billing_address, default_shipping_method, default_payment_method, language, marketing_permission, phone, www, timezone, prefix, name, suffix, name_ext, email, tax_group, contact_ptr)

Bases: shoop.core.models.Contact

exception DoesNotExist

Bases: shoop.core.models._contacts.DoesNotExist

exception AnonymousContact.MultipleObjectsReturned

Bases: shoop.core.models._contacts.MultipleObjectsReturned

AnonymousContact.base_objects = <django.db.models.manager.Manager object>
AnonymousContact.contact_ptr
AnonymousContact.delete(*args, **kwargs)[source]
AnonymousContact.groups
AnonymousContact.id = None
AnonymousContact.is_anonymous = True
AnonymousContact.objects = <polymorphic.managers.PolymorphicManager object>
AnonymousContact.pk = None
AnonymousContact.polymorphic_primary_key_name = 'id'
AnonymousContact.polymorphic_super_sub_accessors_replaced = False
AnonymousContact.save(*args, **kwargs)[source]
class shoop.core.models.Attribute(id, identifier, searchable, type, visibility_mode)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Attribute.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Attribute.formfield(**kwargs)[source]

Get a form field for this attribute.

Parameters:kwargs – Kwargs to pass for the form field class.
Returns:Form field.
Return type:forms.Field
Attribute.get_type_display(*moreargs, **morekwargs)
Attribute.get_visibility_mode_display(*moreargs, **morekwargs)
Attribute.is_null_value(value)[source]

Find out whether the given value is null from this attribute’s point of view.

Parameters:value (object) – A value
Returns:Nulliness boolean
Return type:bool
Attribute.is_numeric
Attribute.is_stringy
Attribute.is_temporal
Attribute.is_translated
Attribute.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Attribute.objects = <django.db.models.manager.ManagerFromAttributeQuerySet object>
Attribute.product_types
Attribute.productattribute_set
Attribute.save(*args, **kwargs)[source]
Attribute.translations
Attribute.type

A placeholder class that provides a way to set the attribute on the model.

Attribute.visibility_mode

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.AttributeType

Bases: enumfields.enums.Enum

class shoop.core.models.AttributeVisibility

Bases: enumfields.enums.Enum

class shoop.core.models.Category(id, parent, identifier, status, image, ordering, visibility)

Bases: mptt.models.MPTTModel, parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Category.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Category.add_log_entry(message, identifier=None, kind=<LogEntryKind.OTHER: 0>, user=None, extra=None, save=True)
Category.children
Category.description

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Category.get_status_display(*moreargs, **morekwargs)
Category.get_visibility_display(*moreargs, **morekwargs)
Category.image
Category.is_visible(customer)[source]
Category.log_entries
Category.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Category.objects = <shoop.core.models._categories.CategoryManager object>
Category.parent
Category.primary_products
Category.primary_shop_products
Category.save(*args, **kwargs)[source]
Category.shop_products
Category.shops
Category.slug

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Category.status

A placeholder class that provides a way to set the attribute on the model.

Category.translations
Category.visibility

A placeholder class that provides a way to set the attribute on the model.

Category.visibility_groups
class shoop.core.models.CategoryStatus

Bases: enumfields.enums.Enum

class shoop.core.models.CategoryVisibility

Bases: enumfields.enums.Enum

class shoop.core.models.CompanyContact(id, polymorphic_ctype, created_on, identifier, is_active, default_shipping_address, default_billing_address, default_shipping_method, default_payment_method, language, marketing_permission, phone, www, timezone, prefix, name, suffix, name_ext, email, tax_group, contact_ptr, tax_number)

Bases: shoop.core.models.Contact

exception DoesNotExist

Bases: shoop.core.models._contacts.DoesNotExist

exception CompanyContact.MultipleObjectsReturned

Bases: shoop.core.models._contacts.MultipleObjectsReturned

CompanyContact.base_objects = <django.db.models.manager.Manager object>
CompanyContact.contact_ptr
CompanyContact.default_tax_group_getter()
CompanyContact.members
CompanyContact.objects = <polymorphic.managers.PolymorphicManager object>
CompanyContact.polymorphic_primary_key_name = 'id'
CompanyContact.polymorphic_super_sub_accessors_replaced = False
class shoop.core.models.ConfigurationItem(id, shop, key, value)

Bases: shoop.core.models._base.ShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ConfigurationItem.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ConfigurationItem.objects = <django.db.models.manager.Manager object>
ConfigurationItem.shop
ConfigurationItem.value

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.Contact(id, polymorphic_ctype, created_on, identifier, is_active, default_shipping_address, default_billing_address, default_shipping_method, default_payment_method, language, marketing_permission, phone, www, timezone, prefix, name, suffix, name_ext, email, tax_group)

Bases: shoop.core.utils.name_mixin.NameMixin, polymorphic.models.PolymorphicModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Contact.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Contact.anonymouscontact
Contact.base_objects = <django.db.models.manager.Manager object>
Contact.company_memberships
Contact.companycontact
Contact.customer_baskets
Contact.customer_orders
Contact.default_billing_address
Contact.default_payment_method
Contact.default_shipping_address
Contact.default_shipping_method
Contact.default_tax_group_getter = None
Contact.get_language_display(*moreargs, **morekwargs)
Contact.get_next_by_created_on(*moreargs, **morekwargs)
Contact.get_previous_by_created_on(*moreargs, **morekwargs)
Contact.get_timezone_display(*moreargs, **morekwargs)
Contact.groups
Contact.is_all_seeing = False
Contact.is_anonymous = False
Contact.objects = <polymorphic.managers.PolymorphicManager object>
Contact.personcontact
Contact.polymorphic_ctype
Contact.polymorphic_primary_key_name = 'id'
Contact.polymorphic_super_sub_accessors_replaced = False
Contact.savedaddress_set
Contact.shop_set
Contact.tax_group
Contact.timezone

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.ContactGroup(id, identifier, show_pricing)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ContactGroup.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ContactGroup.members
ContactGroup.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ContactGroup.objects = <parler.managers.TranslatableManager object>
ContactGroup.simpleproductprice_set
ContactGroup.translations
ContactGroup.visible_categories
ContactGroup.visible_products
class shoop.core.models.Counter(id, value)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Counter.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

classmethod Counter.get_and_increment(id)[source]
Counter.get_id_display(*moreargs, **morekwargs)
Counter.id

A placeholder class that provides a way to set the attribute on the model.

Counter.objects = <django.db.models.manager.Manager object>
class shoop.core.models.CounterType

Bases: enumfields.enums.Enum

class shoop.core.models.CustomerTaxGroup(id, identifier, enabled)

Bases: shoop.core.models._base.TranslatableShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception CustomerTaxGroup.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

CustomerTaxGroup.contact_set
classmethod CustomerTaxGroup.get_default_company_group()[source]
classmethod CustomerTaxGroup.get_default_person_group()[source]
CustomerTaxGroup.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

CustomerTaxGroup.objects = <parler.managers.TranslatableManager object>
CustomerTaxGroup.taxrule_set
CustomerTaxGroup.translations
shoop.core.models.get_person_contact(user)

Get PersonContact of given user.

If given user is non-zero (evaluates true as bool) and not anonymous, return the PersonContact of the user. If there is no PersonContact for the user yet, create it first. When this creation happens, details (name, email, is_active) are copied from the user.

If given user is None (or otherwise evaluates as false) or anonymous, return the AnonymousContact.

Parameters:user (django.contrib.auth.models.User|None) – User object (or None) to get contact for
Returns:PersonContact of the user or AnonymousContact
Return type:PersonContact|AnonymousContact
class shoop.core.models.Gender

Bases: enumfields.enums.Enum

class shoop.core.models.ImmutableAddress(*args, **kwargs)

Bases: shoop.core.models._base.ChangeProtected, shoop.core.models._addresses.Address

An address that can not be changed.

Immutable addresses are used for orders, etc., where subsequent edits to the original address (for example an user’s default address) must not affect past business data.

Immutable addresses can be created directly, with the from_data() method, or by creating an immutable copy of an existing MutableAddress with the Address.to_immutable() method.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ImmutableAddress.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ImmutableAddress.billing_orders
ImmutableAddress.country

A descriptor for country fields on a model instance. Returns a Country when accessed so you can do things like:

>>> from people import Person
>>> person = Person.object.get(name='Chris')

>>> person.country.name
'New Zealand'

>>> person.country.flag
'/static/flags/nz.gif'
classmethod ImmutableAddress.from_data(data)[source]

Get or create immutable address with given data.

Parameters:data (dict[str,str]) – data for address
Returns:Saved immutable address
Return type:ImmutableAddress
ImmutableAddress.get_country_display(*moreargs, **morekwargs)
ImmutableAddress.objects = <django.db.models.manager.Manager object>
ImmutableAddress.shipping_orders
ImmutableAddress.to_immutable()[source]
class shoop.core.models.Manufacturer(id, created_on, identifier, name, url)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Manufacturer.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Manufacturer.get_next_by_created_on(*moreargs, **morekwargs)
Manufacturer.get_previous_by_created_on(*moreargs, **morekwargs)
Manufacturer.objects = <django.db.models.manager.Manager object>
Manufacturer.product_set
class shoop.core.models.MethodStatus

Bases: enumfields.enums.Enum

class shoop.core.models.MethodType

Bases: enumfields.enums.Enum

class shoop.core.models.MutableAddress(*args, **kwargs)

Bases: shoop.core.models._addresses.Address

An address that can be changed.

Mutable addresses are used for e.g. contact’s saved addresses. They are saved as new immutable addresses when used in e.g. orders.

Mutable addresses can be created with MutableAddress.from_data or with the to_mutable method of Address objects.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MutableAddress.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

MutableAddress.country

A descriptor for country fields on a model instance. Returns a Country when accessed so you can do things like:

>>> from people import Person
>>> person = Person.object.get(name='Chris')

>>> person.country.name
'New Zealand'

>>> person.country.flag
'/static/flags/nz.gif'
classmethod MutableAddress.from_data(data)[source]

Construct mutable address from a data dictionary.

Parameters:data (dict[str,str]) – data for address
Returns:Unsaved mutable address
Return type:MutableAddress
MutableAddress.get_country_display(*moreargs, **morekwargs)
MutableAddress.objects = <django.db.models.manager.Manager object>
MutableAddress.saved_addresses
class shoop.core.models.Order(id, shop, created_on, identifier, label, key, reference_number, customer, orderer, billing_address, shipping_address, tax_number, phone, email, creator, deleted, status, payment_status, shipping_status, payment_method, payment_method_name, payment_data, shipping_method, shipping_method_name, shipping_data, extra_data, taxful_total_price_value, taxless_total_price_value, currency, prices_include_tax, display_currency, display_currency_rate, ip_address, order_date, payment_date, language, customer_comment, admin_comment, require_verification, all_verified, marketing_permission)

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Order.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Order.add_log_entry(message, identifier=None, kind=<LogEntryKind.OTHER: 0>, user=None, extra=None, save=True)
Order.billing_address
Order.cache_prices()[source]
Order.can_set_complete()[source]
Order.check_all_verified()[source]
Order.check_and_set_fully_shipped()[source]
Order.create_payment(amount, payment_identifier=None, description='')[source]

Create a payment with given amount for this order.

If the order already has payments and sum of their amounts is equal or greater than self.taxful_total_price, an exception is raised.

If the end sum of all payments is equal or greater than self.taxful_total_price, then the order is marked as paid.

Parameters:
  • amount (Money) – Amount of the payment to be created
  • payment_identifier (str|None) – Identifier of the created payment. If not set, default value of “gateway_id:order_id:number” will be used (where number is number of payments in the order).
  • description (str) – Description of the payment. Will be set to method property of the created payment.
Returns:

The created Payment object

Return type:

shoop.core.models.Payment

Order.create_shipment(supplier, product_quantities)[source]

Create a shipment for this order from product_quantities. product_quantities is expected to be a dict mapping Product instances to quantities.

Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, NoProductsToShipException will be raised.

Parameters:
  • supplier – The Supplier for this product. No validation is made as to whether the given supplier supplies the products.
  • product_quantities (dict[shoop.shop.models.Product, decimal.Decimal]) – a dict mapping Product instances to quantities to ship
Raises:

NoProductsToShipException

Returns:

Saved, complete Shipment object

Return type:

shoop.core.models.Shipment

Order.create_shipment_of_all_products(supplier=None)[source]

Create a shipment of all the products in this Order, no matter whether or not any have been previously marked as shipped or not.

See the documentation for create_shipment.

Parameters:supplier – The Supplier to use. If None, the first supplier in the order is used. (If several are in the order, this fails.)
Returns:Saved, complete Shipment object
Return type:shoop.shop.models.Shipment
Order.creator
Order.customer
Order.delete(using=None)[source]
Order.extra_data

A placeholder class that provides a way to set the attribute on the model.

Order.full_clean(exclude=None, validate_unique=True)[source]
Order.get_known_additional_data()[source]

Get a list of “known additional data” in this order’s payment_data, shipping_data and extra_data. The list is returned in the order the fields are specified in the settings entries for said known keys. dict(that_list) can of course be used to “flatten” the list into a dict. :return: list of 2-tuples.

Order.get_language_display(*moreargs, **morekwargs)
Order.get_next_by_created_on(*moreargs, **morekwargs)
Order.get_next_by_order_date(*moreargs, **morekwargs)
Order.get_payment_status_display(*moreargs, **morekwargs)
Order.get_previous_by_created_on(*moreargs, **morekwargs)
Order.get_previous_by_order_date(*moreargs, **morekwargs)
Order.get_product_ids_and_quantities()[source]
Order.get_product_summary()[source]

Return a dict of product IDs -> {ordered, unshipped, shipped}

Order.get_purchased_attachments()[source]
Order.get_shipping_status_display(*moreargs, **morekwargs)
Order.get_status_display()[source]
Order.get_tax_summary()[source]
Return type:taxing.TaxSummary
Order.get_total_paid_amount()[source]
Order.get_unshipped_products()[source]
Order.is_complete()[source]
Order.is_paid()[source]
Order.lines
Order.log_entries
Order.objects = <django.db.models.manager.ManagerFromOrderQuerySet object>
Order.orderer
Order.payment_data

A placeholder class that provides a way to set the attribute on the model.

Order.payment_method
Order.payment_status

A placeholder class that provides a way to set the attribute on the model.

Order.payments
Order.save(*args, **kwargs)[source]
Order.set_canceled()[source]
Order.shipments
Order.shipping_address
Order.shipping_data

A placeholder class that provides a way to set the attribute on the model.

Order.shipping_method
Order.shipping_status

A placeholder class that provides a way to set the attribute on the model.

Order.shop
Order.status
Order.taxful_total_price
Order.taxless_total_price
class shoop.core.models.OrderLine(id, order, product, supplier, parent_line, ordering, type, sku, text, accounting_identifier, require_verification, verified, extra_data, quantity, base_unit_price_value, discount_amount_value)

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model, shoop.core.pricing.Priceful

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception OrderLine.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

OrderLine.base_unit_price

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

OrderLine.child_lines
OrderLine.discount_amount

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

OrderLine.extra_data

A placeholder class that provides a way to set the attribute on the model.

OrderLine.get_type_display(*moreargs, **morekwargs)
OrderLine.objects = <shoop.core.models._order_lines.OrderLineManager object>
OrderLine.order
OrderLine.parent_line
OrderLine.product
OrderLine.save(*args, **kwargs)[source]
OrderLine.supplier
OrderLine.tax_amount
Return type:shoop.utils.money.Money
OrderLine.taxes
OrderLine.type

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.OrderLineTax(id, order_line, tax, name, amount_value, base_amount_value, ordering)

Bases: shoop.utils.properties.MoneyPropped, shoop.core.models._base.ShoopModel, shoop.core.taxing.LineTax

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception OrderLineTax.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

OrderLineTax.amount

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

OrderLineTax.base_amount

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

OrderLineTax.objects = <django.db.models.manager.Manager object>
OrderLineTax.order_line
OrderLineTax.tax
class shoop.core.models.OrderLineType

Bases: enumfields.enums.Enum

class shoop.core.models.OrderLogEntry(id, created_on, user, message, identifier, kind, extra, target)

Bases: shoop.utils.analog.BaseLogEntry

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception OrderLogEntry.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

OrderLogEntry.extra

A placeholder class that provides a way to set the attribute on the model.

OrderLogEntry.get_kind_display(*moreargs, **morekwargs)
OrderLogEntry.get_next_by_created_on(*moreargs, **morekwargs)
OrderLogEntry.get_previous_by_created_on(*moreargs, **morekwargs)
OrderLogEntry.kind

A placeholder class that provides a way to set the attribute on the model.

OrderLogEntry.logged_model

alias of Order

OrderLogEntry.objects = <django.db.models.manager.Manager object>
OrderLogEntry.target
OrderLogEntry.user
class shoop.core.models.OrderStatus(id, identifier, ordering, role, default)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception OrderStatus.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

OrderStatus.get_role_display(*moreargs, **morekwargs)
OrderStatus.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

OrderStatus.objects = <django.db.models.manager.ManagerFromOrderStatusQuerySet object>
OrderStatus.order_set
OrderStatus.role

A placeholder class that provides a way to set the attribute on the model.

OrderStatus.save(*args, **kwargs)[source]
OrderStatus.translations
class shoop.core.models.OrderStatusRole

Bases: enumfields.enums.Enum

class shoop.core.models.Payment(id, order, created_on, gateway_id, payment_identifier, amount_value, foreign_amount_value, foreign_currency, description)

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Payment.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Payment.amount

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

Payment.foreign_amount

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

Payment.get_next_by_created_on(*moreargs, **morekwargs)
Payment.get_previous_by_created_on(*moreargs, **morekwargs)
Payment.objects = <django.db.models.manager.Manager object>
Payment.order
class shoop.core.models.PaymentMethod(id, tax_class, status, identifier, module_identifier, module_data)

Bases: shoop.core.models._methods.Method

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception PaymentMethod.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

PaymentMethod.contact_set
PaymentMethod.default_module_spec = 'shoop.core.methods.default:DefaultPaymentMethodModule'
PaymentMethod.get_payment_process_response(order, urls)[source]
PaymentMethod.get_status_display(*moreargs, **morekwargs)
PaymentMethod.line_type = <OrderLineType.PAYMENT: 3>
PaymentMethod.module_data

A placeholder class that provides a way to set the attribute on the model.

PaymentMethod.module_provides_key = 'payment_method_module'
PaymentMethod.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

PaymentMethod.objects = <django.db.models.manager.ManagerFromMethodQuerySet object>
PaymentMethod.payment_orders
PaymentMethod.payment_products
PaymentMethod.process_payment_return_request(order, request)[source]
PaymentMethod.shop_product_m2m = 'payment_methods'
PaymentMethod.status

A placeholder class that provides a way to set the attribute on the model.

PaymentMethod.tax_class
PaymentMethod.translations
PaymentMethod.type = <MethodType.PAYMENT: 2>
class shoop.core.models.PaymentStatus

Bases: enumfields.enums.Enum

class shoop.core.models.PersistentCacheEntry(id, module, key, time, data)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception PersistentCacheEntry.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

PersistentCacheEntry.data

A placeholder class that provides a way to set the attribute on the model.

PersistentCacheEntry.get_next_by_time(*moreargs, **morekwargs)
PersistentCacheEntry.get_previous_by_time(*moreargs, **morekwargs)
PersistentCacheEntry.objects = <django.db.models.manager.Manager object>
class shoop.core.models.PersonContact(id, polymorphic_ctype, created_on, identifier, is_active, default_shipping_address, default_billing_address, default_shipping_method, default_payment_method, language, marketing_permission, phone, www, timezone, prefix, name, suffix, name_ext, email, tax_group, contact_ptr, user, gender, birth_date)

Bases: shoop.core.models.Contact

exception DoesNotExist

Bases: shoop.core.models._contacts.DoesNotExist

exception PersonContact.MultipleObjectsReturned

Bases: shoop.core.models._contacts.MultipleObjectsReturned

PersonContact.base_objects = <django.db.models.manager.Manager object>
PersonContact.contact_ptr
PersonContact.default_tax_group_getter()
PersonContact.gender

A placeholder class that provides a way to set the attribute on the model.

PersonContact.get_gender_display(*moreargs, **morekwargs)
PersonContact.is_all_seeing
PersonContact.objects = <polymorphic.managers.PolymorphicManager object>
PersonContact.orderer_baskets
PersonContact.orderer_orders
PersonContact.polymorphic_primary_key_name = 'id'
PersonContact.polymorphic_super_sub_accessors_replaced = False
PersonContact.save(*args, **kwargs)[source]
PersonContact.user
class shoop.core.models.Product(id, created_on, modified_on, deleted, mode, variation_parent, stock_behavior, shipping_mode, sales_unit, tax_class, type, sku, gtin, barcode, accounting_identifier, profit_center, cost_center, category, width, height, depth, net_weight, gross_weight, manufacturer, primary_image)

Bases: shoop.core.taxing.TaxableItem, shoop.core.models._attributes.AttributableMixin, parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Product.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Product.add_log_entry(message, identifier=None, kind=<LogEntryKind.OTHER: 0>, user=None, extra=None, save=True)
Product.attributes
Product.category
Product.clear_variation()[source]

Fully remove variation information.

Make this product a non-variation parent.

Product.cross_sell_1
Product.cross_sell_2
Product.delete(using=None)[source]
Product.description

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.get_all_available_combinations()[source]

Generate all available combinations of variation variables.

If the product is not a variable variation parent, the iterator is empty.

Because of possible combinatorial explosion this is a generator function. (For example 6 variables with 5 options each explodes to 15,625 combinations.)

Returns:Iterable of combination information dicts.
Return type:Iterable[dict]
Product.get_all_package_children()[source]
Product.get_all_package_parents()[source]
Product.get_available_attribute_queryset()[source]
Product.get_available_variation_results()[source]

Get a dict of combination_hash to product ID of variable variation results.

Returns:Mapping of combination hashes to product IDs
Return type:dict[str, int]
Product.get_base_price(context, quantity=1)[source]

Get base price of the product within given context.

Base price differs from the (effective) price when there are discounts in effect.

Return type:shoop.core.pricing.Price
Product.get_cheapest_child_price(context, quantity=1)[source]
Product.get_cheapest_child_price_info(context, quantity=1)[source]

Get the PriceInfo of the cheapest variation child

The attribute used for sorting is PriceInfo.price.

Return None if self.variation_children do not exist. This is because we cannot return anything sensible.

Return type:shoop.core.pricing.PriceInfo
Product.get_child_price_range(context, quantity=1)[source]

Get the prices for cheapest and the most expensive child

The attribute used for sorting is PriceInfo.price.

Return (None, None) if self.variation_children do not exist. This is because we cannot return anything sensible.

Returns:a tuple of prices
Return type:(shoop.core.pricing.Price, shoop.core.pricing.Price)
Product.get_mode_display(*moreargs, **morekwargs)
Product.get_next_by_created_on(*moreargs, **morekwargs)
Product.get_next_by_modified_on(*moreargs, **morekwargs)
Product.get_package_child_to_quantity_map()[source]
Product.get_previous_by_created_on(*moreargs, **morekwargs)
Product.get_previous_by_modified_on(*moreargs, **morekwargs)
Product.get_price(context, quantity=1)[source]

Get price of the product within given context.

Note

When the current pricing module implements pricing steps, it is possible that p.get_price(ctx) * 123 is not equal to p.get_price(ctx, quantity=123), since there could be quantity discounts in effect, but usually they are equal.

Return type:shoop.core.pricing.Price
Product.get_price_info(context, quantity=1)[source]

Get PriceInfo object for the product in given context.

Returned PriceInfo object contains calculated price and base_price. The calculation of prices is handled in the current pricing module.

Return type:shoop.core.pricing.PriceInfo
Product.get_public_media()[source]
Product.get_shipping_mode_display(*moreargs, **morekwargs)
Product.get_shop_instance(shop)[source]
Return type:shoop.core.models.ShopProduct
Product.get_stock_behavior_display(*moreargs, **morekwargs)
Product.get_variation_siblings()[source]
Product.is_package_child()[source]
Product.is_package_parent()[source]
Product.is_variation_child()[source]
Product.is_variation_parent()[source]
Product.keywords

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Parameters:
  • parent (Product) – The parent to link to.
  • variables (dict|None) – Optional dict of {variable identifier: value identifier} for complex variable linkage
  • combination_hash (str|None) – Optional combination hash (for variable variations), if precomputed. Mutually exclusive with variables
Product.log_entries
Product.make_package(package_def)[source]
Product.manufacturer
Product.media
Product.mode

A placeholder class that provides a way to set the attribute on the model.

Product.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.objects = <django.db.models.manager.ManagerFromProductQuerySet object>
Product.order_lines
Product.primary_image
Product.sales_unit
Product.save(*args, **kwargs)[source]
Product.shipments
Product.shipping_mode

A placeholder class that provides a way to set the attribute on the model.

Product.shop_products
Product.simplify_variation()[source]

Remove variation variables from the given variation parent, turning it into a simple variation (or a normal product, if it has no children).

Parameters:product (shoop.core.models.Product) – Variation parent to not be variable any longer.
Product.slug

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.soft_delete(user=None)[source]
Product.status_text

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.stock_behavior

A placeholder class that provides a way to set the attribute on the model.

Product.storedbasket_set
Product.suppliedproduct_set
Product.tax_class
Product.translations
Product.type
Product.variation_children
Product.variation_name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.variation_parent
Product.variation_result_subs
Product.variation_result_supers
Product.variation_variables
Product.verify_mode()[source]
class shoop.core.models.Product(id, created_on, modified_on, deleted, mode, variation_parent, stock_behavior, shipping_mode, sales_unit, tax_class, type, sku, gtin, barcode, accounting_identifier, profit_center, cost_center, category, width, height, depth, net_weight, gross_weight, manufacturer, primary_image)

Bases: shoop.core.taxing.TaxableItem, shoop.core.models._attributes.AttributableMixin, parler.models.TranslatableModel

COMMON_SELECT_RELATED = ('type', 'primary_image', 'tax_class')
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Product.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Product.add_log_entry(message, identifier=None, kind=<LogEntryKind.OTHER: 0>, user=None, extra=None, save=True)
Product.attributes
Product.category
Product.clear_variation()[source]

Fully remove variation information.

Make this product a non-variation parent.

Product.cross_sell_1
Product.cross_sell_2
Product.delete(using=None)[source]
Product.description

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.get_all_available_combinations()[source]

Generate all available combinations of variation variables.

If the product is not a variable variation parent, the iterator is empty.

Because of possible combinatorial explosion this is a generator function. (For example 6 variables with 5 options each explodes to 15,625 combinations.)

Returns:Iterable of combination information dicts.
Return type:Iterable[dict]
Product.get_all_package_children()[source]
Product.get_all_package_parents()[source]
Product.get_available_attribute_queryset()[source]
Product.get_available_variation_results()[source]

Get a dict of combination_hash to product ID of variable variation results.

Returns:Mapping of combination hashes to product IDs
Return type:dict[str, int]
Product.get_base_price(context, quantity=1)[source]

Get base price of the product within given context.

Base price differs from the (effective) price when there are discounts in effect.

Return type:shoop.core.pricing.Price
Product.get_cheapest_child_price(context, quantity=1)[source]
Product.get_cheapest_child_price_info(context, quantity=1)[source]

Get the PriceInfo of the cheapest variation child

The attribute used for sorting is PriceInfo.price.

Return None if self.variation_children do not exist. This is because we cannot return anything sensible.

Return type:shoop.core.pricing.PriceInfo
Product.get_child_price_range(context, quantity=1)[source]

Get the prices for cheapest and the most expensive child

The attribute used for sorting is PriceInfo.price.

Return (None, None) if self.variation_children do not exist. This is because we cannot return anything sensible.

Returns:a tuple of prices
Return type:(shoop.core.pricing.Price, shoop.core.pricing.Price)
Product.get_mode_display(*moreargs, **morekwargs)
Product.get_next_by_created_on(*moreargs, **morekwargs)
Product.get_next_by_modified_on(*moreargs, **morekwargs)
Product.get_package_child_to_quantity_map()[source]
Product.get_previous_by_created_on(*moreargs, **morekwargs)
Product.get_previous_by_modified_on(*moreargs, **morekwargs)
Product.get_price(context, quantity=1)[source]

Get price of the product within given context.

Note

When the current pricing module implements pricing steps, it is possible that p.get_price(ctx) * 123 is not equal to p.get_price(ctx, quantity=123), since there could be quantity discounts in effect, but usually they are equal.

Return type:shoop.core.pricing.Price
Product.get_price_info(context, quantity=1)[source]

Get PriceInfo object for the product in given context.

Returned PriceInfo object contains calculated price and base_price. The calculation of prices is handled in the current pricing module.

Return type:shoop.core.pricing.PriceInfo
Product.get_public_media()[source]
Product.get_shipping_mode_display(*moreargs, **morekwargs)
Product.get_shop_instance(shop)[source]
Return type:shoop.core.models.ShopProduct
Product.get_stock_behavior_display(*moreargs, **morekwargs)
Product.get_variation_siblings()[source]
Product.is_package_child()[source]
Product.is_package_parent()[source]
Product.is_variation_child()[source]
Product.is_variation_parent()[source]
Product.keywords

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.link_to_parent(parent, variables=None, combination_hash=None)[source]
Parameters:
  • parent (Product) – The parent to link to.
  • variables (dict|None) – Optional dict of {variable identifier: value identifier} for complex variable linkage
  • combination_hash (str|None) – Optional combination hash (for variable variations), if precomputed. Mutually exclusive with variables
Product.log_entries
Product.make_package(package_def)[source]
Product.manufacturer
Product.media
Product.mode

A placeholder class that provides a way to set the attribute on the model.

Product.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.objects = <django.db.models.manager.ManagerFromProductQuerySet object>
Product.order_lines
Product.primary_image
Product.sales_unit
Product.save(*args, **kwargs)[source]
Product.shipments
Product.shipping_mode

A placeholder class that provides a way to set the attribute on the model.

Product.shop_products
Product.simplify_variation()[source]

Remove variation variables from the given variation parent, turning it into a simple variation (or a normal product, if it has no children).

Parameters:product (shoop.core.models.Product) – Variation parent to not be variable any longer.
Product.slug

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.soft_delete(user=None)[source]
Product.status_text

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.stock_behavior

A placeholder class that provides a way to set the attribute on the model.

Product.storedbasket_set
Product.suppliedproduct_set
Product.tax_class
Product.translations
Product.type
Product.unlink_from_parent()[source]
Product.variation_children
Product.variation_name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Product.variation_parent
Product.variation_result_subs
Product.variation_result_supers
Product.variation_variables
Product.verify_mode()[source]
class shoop.core.models.ProductAttribute(id, attribute, numeric_value, datetime_value, untranslated_string_value, product)

Bases: shoop.core.models._attributes.AppliedAttribute

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductAttribute.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductAttribute.attribute
ProductAttribute.objects = <parler.managers.TranslatableManager object>
ProductAttribute.product
ProductAttribute.translated_string_value

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductAttribute.translations
class shoop.core.models.ProductCrossSell(id, product1, product2, weight, type)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductCrossSell.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductCrossSell.get_type_display(*moreargs, **morekwargs)
ProductCrossSell.objects = <django.db.models.manager.Manager object>
ProductCrossSell.product1
ProductCrossSell.product2
ProductCrossSell.type

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.ProductCrossSellType

Bases: enumfields.enums.Enum

class shoop.core.models.ProductMedia(id, identifier, product, kind, file, external_url, ordering, enabled, public, purchased)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductMedia.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductMedia.description

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductMedia.easy_thumbnails_thumbnailer

Get Thumbnailer instance.

Will return None if file cannot be thumbnailed.

:rtype:easy_thumbnails.files.Thumbnailer|None

ProductMedia.effective_title
ProductMedia.file
ProductMedia.get_kind_display(*moreargs, **morekwargs)
ProductMedia.get_thumbnail(**kwargs)[source]

Get thumbnail for image

This will return None if there is no file or kind is not ProductMediaKind.IMAGE

Return type:easy_thumbnails.files.ThumbnailFile|None
ProductMedia.kind

A placeholder class that provides a way to set the attribute on the model.

ProductMedia.objects = <parler.managers.TranslatableManager object>
ProductMedia.primary_image_for_products
ProductMedia.primary_image_for_shop_products
ProductMedia.product
ProductMedia.shops
ProductMedia.title

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductMedia.translations
ProductMedia.url
class shoop.core.models.ProductMediaKind

Bases: enumfields.enums.Enum

class shoop.core.models.ProductMode

Bases: enumfields.enums.Enum

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductPackageLink.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductPackageLink.child
ProductPackageLink.objects = <django.db.models.manager.Manager object>
ProductPackageLink.parent
class shoop.core.models.ProductType(id, identifier)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductType.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductType.attributes
ProductType.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductType.objects = <parler.managers.TranslatableManager object>
ProductType.products
ProductType.translations
class shoop.core.models.ProductVariationLinkStatus

Bases: enumfields.enums.Enum

class shoop.core.models.ProductVariationResult(id, product, combination_hash, result, status)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductVariationResult.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductVariationResult.get_status_display(*moreargs, **morekwargs)
ProductVariationResult.objects = <django.db.models.manager.Manager object>
ProductVariationResult.product
classmethod ProductVariationResult.resolve(parent_product, combination)[source]
ProductVariationResult.result
ProductVariationResult.status

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.ProductVariationVariable(id, product, identifier)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductVariationVariable.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductVariationVariable.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductVariationVariable.objects = <parler.managers.TranslatableManager object>
ProductVariationVariable.product
ProductVariationVariable.translations
ProductVariationVariable.values
class shoop.core.models.ProductVariationVariableValue(id, variable, identifier)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ProductVariationVariableValue.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ProductVariationVariableValue.objects = <parler.managers.TranslatableManager object>
ProductVariationVariableValue.translations
ProductVariationVariableValue.value

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ProductVariationVariableValue.variable
class shoop.core.models.ProductVisibility

Bases: enumfields.enums.Enum

class shoop.core.models.SalesUnit(id, identifier, decimals)

Bases: parler.models.TranslatableModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception SalesUnit.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

SalesUnit.allow_fractions
SalesUnit.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

SalesUnit.objects = <parler.managers.TranslatableManager object>
SalesUnit.product_set
SalesUnit.quantity_step

Get the quantity increment for the amount of decimals this unit allows.

For 0 decimals, this will be 1; for 1 decimal, 0.1; etc.

Returns:Decimal in (0..1]
Return type:Decimal
SalesUnit.round(value)[source]
SalesUnit.short_name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

SalesUnit.translations
class shoop.core.models.SavedAddress(*args, **kwargs)

Bases: shoop.core.models._base.ShoopModel

Model for saving multiple addresses in an ‘address book’ of sorts.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception SavedAddress.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

SavedAddress.address
SavedAddress.get_role_display(*moreargs, **morekwargs)
SavedAddress.get_status_display(*moreargs, **morekwargs)
SavedAddress.get_title()[source]

Returns the display title for this SavedAddress instance. Defaults to a short representation of the address.

This method should be used instead of accessing the title field directly when displaying SavedAddress objects.

SavedAddress.objects = <shoop.core.models._addresses.SavedAddressManager object>
SavedAddress.owner
SavedAddress.role

A placeholder class that provides a way to set the attribute on the model.

SavedAddress.status

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.SavedAddressRole

Bases: enumfields.enums.Enum

class shoop.core.models.SavedAddressStatus

Bases: enumfields.enums.Enum

class shoop.core.models.Shipment(id, order, supplier, created_on, status, tracking_code, description, volume, weight)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Shipment.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Shipment.cache_values()[source]

(Re)cache volume and weight for this Shipment from the ShipmentProducts within.

Shipment.get_next_by_created_on(*moreargs, **morekwargs)
Shipment.get_previous_by_created_on(*moreargs, **morekwargs)
Shipment.get_status_display(*moreargs, **morekwargs)
Shipment.objects = <django.db.models.manager.Manager object>
Shipment.order
Shipment.products
Shipment.status

A placeholder class that provides a way to set the attribute on the model.

Shipment.supplier
Shipment.total_products
class shoop.core.models.ShipmentProduct(id, shipment, product, quantity, unit_volume, unit_weight)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ShipmentProduct.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ShipmentProduct.cache_values()[source]
ShipmentProduct.objects = <django.db.models.manager.Manager object>
ShipmentProduct.product
ShipmentProduct.shipment
class shoop.core.models.ShippingMethod(id, tax_class, status, identifier, module_identifier, module_data)

Bases: shoop.core.models._methods.Method

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ShippingMethod.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ShippingMethod.contact_set
ShippingMethod.default_module_spec = 'shoop.core.methods.default:DefaultShippingMethodModule'
ShippingMethod.get_status_display(*moreargs, **morekwargs)
ShippingMethod.line_type = <OrderLineType.SHIPPING: 2>
ShippingMethod.module_data

A placeholder class that provides a way to set the attribute on the model.

ShippingMethod.module_provides_key = 'shipping_method_module'
ShippingMethod.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

ShippingMethod.objects = <django.db.models.manager.ManagerFromMethodQuerySet object>
ShippingMethod.shipping_orders
ShippingMethod.shipping_products
ShippingMethod.shop_product_m2m = 'shipping_methods'
ShippingMethod.status

A placeholder class that provides a way to set the attribute on the model.

ShippingMethod.tax_class
ShippingMethod.translations
ShippingMethod.type = <MethodType.SHIPPING: 1>
class shoop.core.models.ShippingMode

Bases: enumfields.enums.Enum

class shoop.core.models.ShippingStatus

Bases: enumfields.enums.Enum

class shoop.core.models.Shop(id, identifier, domain, status, owner, options, currency, prices_include_tax, logo, maintenance_mode)

Bases: shoop.core.models._base.ChangeProtected, shoop.core.models._base.TranslatableShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Shop.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Shop.categories
Shop.change_protect_message = <django.utils.functional.lazy.<locals>.__proxy__ object>
Shop.create_price(value)[source]

Create a price with given value and settings of this shop.

Takes the prices_include_tax and currency settings of this Shop into account.

Return type:shoop.core.pricing.Price
Shop.discountedproductprice_set
Shop.get_status_display(*moreargs, **morekwargs)
Shop.maintenance_message

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Shop.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Shop.objects = <parler.managers.TranslatableManager object>
Shop.options

A placeholder class that provides a way to set the attribute on the model.

Shop.order_set
Shop.owner
Shop.product_media
Shop.protected_fields = ['currency', 'prices_include_tax']
Shop.public_name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Shop.shop_products
Shop.simpleproductprice_set
Shop.status

A placeholder class that provides a way to set the attribute on the model.

Shop.storedbasket_set
Shop.translations
class shoop.core.models.ShopProduct(id, shop, product, visible, listed, purchasable, searchable, visibility_limit, purchase_multiple, minimum_purchase_quantity, limit_shipping_methods, limit_payment_methods, primary_category, shop_primary_image, default_price_value)

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ShopProduct.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ShopProduct.categories
ShopProduct.default_price

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

ShopProduct.get_orderability_errors(supplier, quantity, customer, ignore_minimum=False)[source]

Yield ValidationErrors that would cause this product to not be orderable.

Parameters:
  • supplier (shoop.core.models.Supplier) – Supplier to order this product from. May be None.
  • quantity (int|Decimal) – Quantity to order.
  • customer (shoop.core.models.Contact) – Customer contact.
  • ignore_minimum (bool) – Ignore any limitations caused by quantity minimums.
Returns:

Iterable[ValidationError]

ShopProduct.get_visibility_errors(customer)[source]
ShopProduct.get_visibility_limit_display(*moreargs, **morekwargs)
ShopProduct.images
ShopProduct.is_list_visible()[source]

Return True if this product should be visible in listings in general, without taking into account any other visibility limitations. :rtype: bool

ShopProduct.is_orderable(supplier, customer, quantity)[source]
ShopProduct.objects = <django.db.models.manager.Manager object>
ShopProduct.payment_methods
ShopProduct.primary_category
ShopProduct.primary_image
ShopProduct.product
ShopProduct.quantity_step

Quantity step for purchasing this product.

Return type:decimal.Decimal
Example:
<input type=”number” step=”{{ shop_product.quantity_step }}”>
ShopProduct.raise_if_not_orderable(supplier, customer, quantity, ignore_minimum=False)[source]
ShopProduct.raise_if_not_visible(customer)[source]
ShopProduct.rounded_minimum_purchase_quantity

The minimum purchase quantity, rounded to the sales unit’s precision.

Return type:decimal.Decimal
Example:
<input type=”number”
min=”{{ shop_product.rounded_minimum_purchase_quantity }}” value=”{{ shop_product.rounded_minimum_purchase_quantity }}”>
ShopProduct.shipping_methods
ShopProduct.shop
ShopProduct.shop_primary_image
ShopProduct.suppliers
ShopProduct.visibility_groups
ShopProduct.visibility_limit

A placeholder class that provides a way to set the attribute on the model.

class shoop.core.models.ShopStatus

Bases: enumfields.enums.Enum

class shoop.core.models.StockBehavior

Bases: enumfields.enums.Enum

class shoop.core.models.SuppliedProduct(id, supplier, product, sku, alert_limit, physical_count, logical_count)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception SuppliedProduct.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

SuppliedProduct.objects = <django.db.models.manager.Manager object>
SuppliedProduct.product
SuppliedProduct.supplier
class shoop.core.models.Supplier(id, identifier, name, type, stock_managed, module_identifier, module_data)

Bases: shoop.core.modules.interface.ModuleInterface, shoop.core.models._base.ShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Supplier.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Supplier.adjust_stock(product_id, delta, created_by=None)[source]
Supplier.default_module_spec = 'shoop.core.suppliers:BaseSupplierModule'
Supplier.get_orderability_errors(shop_product, quantity, customer)[source]
Parameters:
Return type:

iterable[ValidationError]

Supplier.get_stock_status(product_id)[source]
Parameters:product_id (int) – Product ID
Return type:shoop.core.stocks.ProductStockStatus
Supplier.get_stock_statuses(product_ids)[source]
Parameters:product_ids – Iterable of product IDs
Returns:Dict of {product_id: ProductStockStatus}
Return type:dict[int, shoop.core.stocks.ProductStockStatus]
Supplier.get_type_display(*moreargs, **morekwargs)
Supplier.module_data

A placeholder class that provides a way to set the attribute on the model.

Supplier.module_provides_key = 'supplier_module'
Supplier.objects = <django.db.models.manager.Manager object>
Supplier.order_lines
Supplier.shipments
Supplier.shop_products
Supplier.stockadjustment_set
Supplier.stockcount_set
Supplier.suppliedproduct_set
Supplier.type

A placeholder class that provides a way to set the attribute on the model.

Supplier.update_stock(product_id)[source]
Supplier.update_stocks(product_ids)[source]
class shoop.core.models.SupplierType

Bases: enumfields.enums.Enum

class shoop.core.models.Tax(id, code, rate, amount_value, currency, enabled)

Bases: shoop.utils.properties.MoneyPropped, shoop.core.models._base.ChangeProtected, shoop.core.models._base.TranslatableShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Tax.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Tax.amount

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

Tax.calculate_amount(base_amount)[source]

Calculate tax amount with this tax for given base amount.

Return type:shoop.utils.money.Money
Tax.change_protect_message = <django.utils.functional.lazy.<locals>.__proxy__ object>
Tax.clean()[source]
Tax.identifier_attr = 'code'
Tax.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Tax.objects = <parler.managers.TranslatableManager object>
Tax.order_line_taxes
Tax.taxrule_set
Tax.translations
Tax.unprotected_fields = ['enabled']
class shoop.core.models.TaxClass(id, identifier, enabled)

Bases: shoop.core.models._base.TranslatableShoopModel

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception TaxClass.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

TaxClass.name

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

TaxClass.objects = <parler.managers.TranslatableManager object>
TaxClass.paymentmethod_set
TaxClass.product_set
TaxClass.shippingmethod_set
TaxClass.taxrule_set
TaxClass.translations
shoop.core.modules package
Submodules
shoop.core.modules.interface module
exception shoop.core.modules.interface.ModuleNotFound[source]

Bases: ValueError

class shoop.core.modules.interface.ModuleInterface[source]

Bases: object

default_module_spec = None
module_identifier = None
module_options_field = 'module_data'
module_provides_key = None
module
classmethod get_module_choices(empty_label=None)[source]
classmethod get_module_implementation_map()[source]

Get a dict that maps module spec identifiers (short strings) into actual spec names.

As an example:

{"Eggs": "foo_package.bar_module:EggsClass"}
Return type:dict[str, str]
Module contents
class shoop.core.modules.ModuleInterface[source]

Bases: object

default_module_spec = None
classmethod get_module_choices(empty_label=None)[source]
classmethod get_module_implementation_map()[source]

Get a dict that maps module spec identifiers (short strings) into actual spec names.

As an example:

{"Eggs": "foo_package.bar_module:EggsClass"}
Return type:dict[str, str]
module
module_identifier = None
module_options_field = 'module_data'
module_provides_key = None
shoop.core.order_creator package
Submodules
shoop.core.order_creator.signals module
Module contents
class shoop.core.order_creator.OrderCreator(request)[source]

Bases: object

add_line_taxes(lines)[source]
add_lines_into_order(order, lines)[source]
create_order(order_source)[source]
create_package_children(order_line)[source]
get_source_order_lines(source, order)[source]
process_order_after_lines(source, order)[source]
process_order_before_lines(source, order)[source]
process_saved_order_line(order, order_line)[source]

Called in sequence for all order lines to be saved into the order. These have all been saved, so they have PKs. :type order: Order :type order_line: OrderLine

source_line_to_order_lines(order, source_line)[source]

Convert a SourceLine into one or more OrderLines (yield them) :param order: The order :param source_line: The SourceLine

class shoop.core.order_creator.OrderSource(shop)[source]

Bases: object

A “provisional order” object.

Contains data that’s not strictly about a basket’s contents, but is useful for things that need to calculate something based on the basket’s contents and extra data, such as shipping/billing addresses.

The core API of OrderCreator reads an OrderSource.

No objects held here need be saved, but they may be.

add_line(**kwargs)[source]
calculate_taxes(force_recalculate=False)[source]
calculate_taxes_or_raise()[source]
get_final_lines(with_taxes=False)[source]

Get lines with processed lines added.

This implementation includes the all lines returned by get_lines and in addition, lines from shipping and payment methods, but these lines can be extended, deleted or replaced by a subclass (by overriding _compute_processed_lines method) and with the post_compute_source_lines signal.

Note

By default, taxes for the returned lines are not calculated when self.calculate_taxes_automatically is false. Pass in True to with_taxes argument or use calculate_taxes method to force tax calculation.

get_lines()[source]

Get unprocessed lines in this OrderSource.

See also get_final_lines.

get_validation_errors()[source]
payment_method
shipping_method
status
taxful_total_discount

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

taxful_total_discount_or_none

Property that turns TaxesNotCalculated exception to None.

Used to implement the OrderSource taxful/taxless total price properties with the “_or_none” suffix.

taxful_total_price

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

taxful_total_price_or_none

Property that turns TaxesNotCalculated exception to None.

Used to implement the OrderSource taxful/taxless total price properties with the “_or_none” suffix.

taxless_total_discount

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

taxless_total_discount_or_none

Property that turns TaxesNotCalculated exception to None.

Used to implement the OrderSource taxful/taxless total price properties with the “_or_none” suffix.

taxless_total_price

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

taxless_total_price_or_none

Property that turns TaxesNotCalculated exception to None.

Used to implement the OrderSource taxful/taxless total price properties with the “_or_none” suffix.

total_discount

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

total_price

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

total_price_of_products

Property that calculates sum of prices.

Used to implement various total price proprties to OrderSource.

uncache()[source]

Uncache processed lines.

Should be called after changing the contents before (re)accessing lines with get_final_lines.

update(**values)[source]
update_from_order(order)[source]
class shoop.core.order_creator.SourceLine(source, **kwargs)[source]

Bases: shoop.core.taxing.TaxableItem, shoop.core.pricing.Priceful

Line of OrderSource.

Note: Properties like price, taxful_price, tax_rate, etc. are inherited from the Priceful mixin.

Initialize SourceLine with given source and data.

Parameters:
base_unit_price = None
discount_amount = None
classmethod from_dict(source, data)[source]

Create SourceLine from given OrderSource and dict.

Return type:cls
get(key, default=None)[source]
quantity = None
tax_amount
Return type:shoop.utils.money.Money
tax_class
to_dict()[source]
update(**kwargs)[source]
exception shoop.core.order_creator.TaxesNotCalculated[source]

Bases: TypeError

Requested tax calculated price but taxes are not calculated.

Raised when requesting a price with taxful/taxless mismatching with shop.prices_include_tax and taxes are not yet calculated.

shoop.core.pricing package
Submodules
shoop.core.pricing.default_pricing module
class shoop.core.pricing.default_pricing.DefaultPricingContext(**kwargs)[source]

Bases: shoop.core.pricing.PricingContext

REQUIRED_VALUES = ['shop']
shop = None
class shoop.core.pricing.default_pricing.DefaultPricingModule[source]

Bases: shoop.core.pricing.PricingModule

identifier = 'default_pricing'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
pricing_context_class

alias of DefaultPricingContext

get_context_from_request(request)[source]

Inject shop into pricing context.

Shop information is used to find correct ShopProduct in self.get_price_info

get_price_info(context, product, quantity=1)[source]

Return a PriceInfo calculated from ShopProduct.default_price

Since ShopProduct.default_price can be None it will be set to zero (0) if None.

Module contents

Shoop modular product pricing functionality.

The pricing module in use is declared by the SHOOP_PRICING_MODULE setting. The default is a pricing module that always prices everything to be free. The base distribution contains shoop.simple_pricing, which is an useful pricing module for many cases.

To acquire an instance of the current pricing module, use get_pricing_module.

In brief, a pricing module is able to price a product based on a context; what exactly a context contains is determined by the module in question. You can construct a context from a request by calling the module’s get_context_from_request method, or for more advanced uses, when you do not have access to an HTTP request, get_context_from_data.

After you have acquired the module and a context, you can calculate prices for a product with the module’s get_price_info method. (Product objects contain the convenience methods get_price_info, get_price, and get_base_price which do these steps for you.)

If you have multiple products, it will likely be more efficient – depending on the implementation of the module – to use the get_price_infos method.

TODO: document the concepts of base price and the pricing steps API. TODO: caching.

class shoop.core.pricing.Price

Bases: shoop.utils.money.Money

Money amount with taxful/taxless info.

Taxful and taxless prices cannot be mixed in comparison or in calculations, i.e. operations like x < y or x + y for two Prices x and y with x.includes_tax != y.includes_tax will raise an UnitMixupError.

In addition to includes_tax info, Prices are Money and know their value and currency. To get the bare Money amount of a Price, use the amount property.

amount

Money amount of this price.

Return type:Money
classmethod from_data(value, currency, includes_tax=None)[source]
includes_tax = None
unit_matches_with(other)[source]
class shoop.core.pricing.Priceful

Bases: object

Mixin to define price properties based on other price properties.

You must provide at least

and both

  • base_unit_price (Price) and
  • discount_amount (Price)

or both

You may also provide

to get various tax related properties.

Provided base_unit_price, discount_amount, price, base_price, and tax_amount must have compatible units (i.e. same taxness and currency).

Invariants:
  • price = base_unit_price * quantity - discount_amount
  • discount_amount = base_price - price
  • discount_rate = 1 - (price / base_price)
  • discount_percentage = 100 * discount_rate
  • unit_discount_amount = discount_amount / quantity
  • taxful_price = taxless_price + tax_amount
  • tax_rate = (taxful_price.amount / taxless_price.amount) - 1
  • tax_percentage = 100 * tax_rate
base_price

Total price for the specified quantity excluding discount.

Return type:shoop.core.pricing.Price
base_unit_price

Undiscounted unit price.

Note: If quantity is 0, will return base_price.

Return type:shoop.core.pricing.Price
discount_amount

Amount of discount for the total quantity.

Return type:shoop.core.pricing.Price
discount_percentage

Discount percentage, 100 meaning totally discounted.

See discount_rate.

Return type:decimal.Decimal
discount_rate

Discount rate, 1 meaning totally discounted.

Note: Could be negative, when base price is smaller than effective price. Could also be greater than 1, when effective price is negative.

If base price is 0, will return 0.

Return type:decimal.Decimal
discounted_unit_price

Unit price with discount.

If quantity is 0, will return base_unit_price - discount_amount.

Return type:shoop.core.pricing.Price
is_discounted

Check if there is a discount in effect.

Returns:True, iff price < base price.
price

Total price for the specified quantity with discount.

Return type:shoop.core.pricing.Price
tax_percentage
Return type:decimal.Decimal
tax_rate
Return type:decimal.Decimal
taxful_base_price

Taxful base_price

taxful_base_unit_price

Taxful base_unit_price

taxful_discount_amount

Taxful discount_amount

taxful_discounted_unit_price

Taxful discounted_unit_price

taxful_price
Return type:TaxfulPrice
taxful_unit_discount_amount

Taxful unit_discount_amount

taxless_base_price

Taxless base_price

taxless_base_unit_price

Taxless base_unit_price

taxless_discount_amount

Taxless discount_amount

taxless_discounted_unit_price

Taxless discounted_unit_price

taxless_price
Return type:TaxlessPrice
taxless_unit_discount_amount

Taxless unit_discount_amount

unit_discount_amount

Discount amount per unit.

If quantity is 0, will return discount_amount.

Return type:shoop.core.pricing.Price
class shoop.core.pricing.PriceInfo(price, base_price, quantity, expires_on=None)

Bases: shoop.core.pricing.Priceful

Object for passing around pricing data of an item.

Initialize PriceInfo with prices and other parameters.

Prices can be taxful or taxless, but their types must match.

Parameters:
  • price (Price) – Effective price for the specified quantity.
  • base_price (Price) – Base price for the specified quantity. Discounts are calculated based on this.
  • quantity (numbers.Number) – Quantity that the given price is for. Unit price is calculated by discounted_unit_price = price / quantity. Note: Quantity could be non-integral (i.e. decimal).
  • expires_on (numbers.Number|None) – Timestamp, comparable to values returned by time.time, determining the point in time when the prices are no longer valid, or None if no expire time is set (which could mean indefinitely, but in reality, it just means undefined).
base_price = None
price = None
quantity = None
class shoop.core.pricing.PricingContext(**kwargs)

Bases: shoop.core.pricing.PricingContextable

Context for pricing.

REQUIRED_VALUES = ()
cache_key
get_cache_key()[source]
get_cache_key_parts()[source]
class shoop.core.pricing.PricingContextable

Bases: object

Object that is or can be converted to a pricing context.

Currently there exists two kind of PricingContextable objects: PricingContext`(and its subclasses) and `HttpRequest.

Note

Expression isinstance(request, PricingContextable) will return True for a request which is HttpRequest, because HttpRequest is registered as a subclass of this abstract base class.

This abstract base class is just a helper to allow writing simpler type specifiers, since we want to allow passing HttpRequest as a pricing context even though it is not a PricingContext.

class shoop.core.pricing.PricingModule

Bases: object

get_context(context)[source]

Create pricing context from pricing contextable object.

Return type:PricingContext
get_context_from_data(**context_data)[source]

Create pricing context from keyword arguments.

Return type:PricingContext
get_context_from_request(request)[source]

Create pricing context from HTTP request.

This base class implementation does not use request at all.

Return type:PricingContext
get_price_info(context, product, quantity=1)[source]

Get price info of product for given quantity.

Parameters:product (shoop.core.models.Product|int) – Product object or id of Product
Return type:PriceInfo
get_price_infos(context, products, quantity=1)[source]

Get PriceInfo objects for a bunch of products.

Returns a dict with product id as key and PriceInfo as value.

May be faster than doing get_price_info for each product separately, since inheriting class may override this.

Parameters:products (Iterable[shoop.core.models.Product|int]) – List of product objects or id’s
Return type:dict[int,PriceInfo]
get_pricing_steps(context, product)[source]

Get context-specific list pricing steps for the given product.

Returns a list of PriceInfos [pi0, pi1, pi2, ...] where each PriceInfo object is at the border unit price change: unit price for 0 <= quantity < pi1.quantity1 is pi0.discounted_unit_price, and unit price for pi1.quantity <= quantity < pi2.quantity is pi1.discounted_unit_price, and so on.

If there are “no steps”, the return value will be a list of single PriceInfo object with the constant price, i.e. [price_info].

Parameters:product (shoop.core.models.Product|int) – Product or product id
Return type:list[PriceInfo]
get_pricing_steps_for_products(context, products)[source]

Get pricing steps for a bunch of products.

Returns a dict with product id as key and step data (as list of PriceInfos) as values.

May be faster than doing get_pricing_steps for each product separately, since inheriting class may override this.

Parameters:products (Iterable[shoop.core.models.Product|int]) – List of product objects or id’s
Return type:dict[int,list[PriceInfo]]
identifier = None
name = None
pricing_context_class

alias of PricingContext

class shoop.core.pricing.TaxfulPrice

Bases: shoop.core.pricing.Price

Price which includes taxes.

Check the base class, Price, for more info.

includes_tax = True
class shoop.core.pricing.TaxlessPrice

Bases: shoop.core.pricing.Price

Price which does not include taxes.

Check the base class, Price, for more info.

includes_tax = False
shoop.core.pricing.get_pricing_module()
Return type:shoop.core.pricing.PricingModule
shoop.core.shortcuts package
Module contents
shoop.core.shortcuts.update_order_line_from_product(pricing_context, order_line, product, quantity=1, supplier=None)[source]

Update OrderLine data from a product.

This is a convenience method for simple applications.

shoop.core.stocks package
Module contents
class shoop.core.stocks.ProductStockStatus(product=None, product_id=None, logical_count=0, physical_count=0, message=None, error=None)[source]

Bases: shoop.core.utils.product_caching_object.ProductCachingObject

shoop.core.suppliers package
Submodules
shoop.core.suppliers.base module
class shoop.core.suppliers.base.BaseSupplierModule(supplier, options)[source]

Bases: object

Base supplier module implementation.

identifier = None
name = None
get_stock_statuses(product_ids)[source]
Parameters:product_ids – Iterable of product IDs
Returns:Dict of {product_id: ProductStockStatus}
Return type:dict[int, shoop.core.stocks.ProductStockStatus]
get_stock_status(product_id)[source]
Parameters:product_id (int) – Product ID
Return type:shoop.core.stocks.ProductStockStatus
get_orderability_errors(shop_product, quantity, customer)[source]
Parameters:
Return type:

iterable[ValidationError]

adjust_stock(product_id, delta, created_by=None)[source]
update_stock(product_id)[source]
update_stocks(product_ids)[source]
Module contents
class shoop.core.suppliers.BaseSupplierModule(supplier, options)[source]

Bases: object

Base supplier module implementation.

adjust_stock(product_id, delta, created_by=None)[source]
get_orderability_errors(shop_product, quantity, customer)[source]
Parameters:
Return type:

iterable[ValidationError]

get_stock_status(product_id)[source]
Parameters:product_id (int) – Product ID
Return type:shoop.core.stocks.ProductStockStatus
get_stock_statuses(product_ids)[source]
Parameters:product_ids – Iterable of product IDs
Returns:Dict of {product_id: ProductStockStatus}
Return type:dict[int, shoop.core.stocks.ProductStockStatus]
identifier = None
name = None
update_stock(product_id)[source]
update_stocks(product_ids)[source]
shoop.core.taxing package
Submodules
shoop.core.taxing.utils module
shoop.core.taxing.utils.stacked_value_added_taxes(price, taxes)[source]

Stack added taxes on the given price without compounding.

Note that this will not take compound taxation (Quebec) into account.

Parameters:
  • price (shoop.core.pricing.Price) – Taxful or taxless price to calculate taxes for
  • taxes (list[shoop.core.models.Tax]) – List of Tax objects
Returns:

TaxedPrice with the calculated taxes.

Return type:

TaxedPrice

shoop.core.taxing.utils.calculate_compounded_added_taxes(price, tax_groups)[source]

Calculate compounded and added taxes from given groups of taxes.

The tax_groups argument should be a list of tax groups, where each tax group is a list of Tax objects. Taxes in each tax group will be added together and finally each added tax group will be compounded over each other.

Parameters:
  • price (shoop.core.pricing.Price) – Taxful or taxless price to calculate taxes for
  • tax_groups (list[list[shoop.core.models.Tax]]) – List of tax groups, each being a list of taxes
Returns:

TaxedPrice with the calculated taxes.

Return type:

TaxedPrice

Module contents
class shoop.core.taxing.LineTax

Bases: object

Tax of some line.

This is an interface for specifying taxes of an OrderLine or SourceLine.

tax

(Tax) The tax that this line is about.

name

(str) Name of the tax.

amount

(Money) Tax amount.

base_amount

(Money) Amount that this tax is calculated from.

classmethod from_tax(tax, base_amount, **kwargs)[source]

Create tax line for given tax and base amount.

rate
class shoop.core.taxing.SourceLineTax(tax, name, amount, base_amount)

Bases: shoop.core.taxing.LineTax

Initialize line tax from given values.

class shoop.core.taxing.TaxModule

Bases: object

Module for calculating taxes.

add_taxes(source, lines)[source]

Add taxes to given OrderSource lines.

Given lines are modified in-place, also new lines may be added (with lines.extend for example). If there is any existing taxes for the lines, they are simply replaced.

Parameters:
get_context_from_data(**context_data)[source]
get_context_from_order_source(source)[source]
get_context_from_request(request)[source]
get_taxed_price_for(context, item, price)[source]

Get TaxedPrice for taxable item.

Taxable items could be products (Product), shipping and payment methods (Method), and lines (SourceLine).

Parameters:
Return type:

shoop.core.taxing.TaxedPrice

identifier = None
name = None
taxing_context_class

alias of TaxingContext

class shoop.core.taxing.TaxSummary

Bases: list

classmethod from_line_taxes(line_taxes, untaxed)[source]

Create TaxSummary from LineTaxes.

Parameters:
  • line_taxes (list[LineTax]) – List of line taxes to summarize
  • untaxed (shoop.core.pricing.TaxlessPrice) – Sum of taxless prices that have no taxes added
class shoop.core.taxing.TaxableItem

Bases: object

tax_class
Return type:shoop.core.models.TaxClass
class shoop.core.taxing.TaxedPrice(taxful, taxless, taxes=None)

Bases: object

Price with calculated taxes.

taxful

(TaxfulPrice) Price including taxes.

taxless

(TaxlessPrice) Pretax price.

taxes

(list[shoop.core.taxing.LineTax]) List of taxes applied to the price.

Initialize from given prices and taxes.

Parameters:
tax_amount

Total amount of applied taxes.

tax_rate

Tax rate calculated from taxful and taxless amounts.

class shoop.core.taxing.TaxingContext(customer_tax_group=None, customer_tax_number=None, location=None)

Bases: object

shoop.core.taxing.get_tax_module()

Get the TaxModule specified in settings.

Return type:shoop.core.taxing.TaxModule
shoop.core.templatetags package
Submodules
shoop.core.templatetags.shoop_common module
shoop.core.templatetags.shoop_common.money(amount, digits=None, widen=0)[source]

Format money amount according to current locale settings.

Parameters:
  • amount (shoop.utils.money.Money) – Money or Price object to format
  • digits (int|None) – Number of digits to use, by default use locale’s default
  • widen (int) – Number of extra digits to add; for formatting with additional precision, e.g. widen=3 will use 5 digits instead of 2
Returns:

Formatted string representing the given amount

Return type:

str

shoop.core.templatetags.shoop_common.percent(value, ndigits=0)[source]
shoop.core.templatetags.shoop_common.number(value)[source]
shoop.core.templatetags.shoop_common.datetime(value, kind='datetime', format='medium', tz=True)[source]

Format a datetime for human consumption.

The currently active locale’s formatting rules are used. The output of this function is probably not machine-parseable.

Parameters:
  • value (datetime.datetime) – datetime object to format
  • kind (str) – Format as ‘datetime’, ‘date’ or ‘time’
  • format (str) – Format specifier or one of ‘full’, ‘long’, ‘medium’ or ‘short’
  • tz (bool|str) –

    Convert to current or given timezone. Accepted values are:

    True (default)
    convert to currently active timezone (as reported by django.utils.timezone.get_current_timezone)
    False (or other false value like empty string)
    do no convert to any timezone (use UTC)
    Other values (as str)
    convert to given timezone (e.g. "US/Hawaii")
shoop.core.templatetags.shoop_common.json(value)[source]
Module contents
shoop.core.utils package
Submodules
shoop.core.utils.form_mixins module
class shoop.core.utils.form_mixins.ProtectedFieldsMixin(**kwargs)[source]

Bases: object

change_protect_field_text = <django.utils.functional.lazy.<locals>.__proxy__ object>
disable_protected_fields()[source]
clean_protected_fields(cleaned_data)[source]

Ignore protected fields (they are set to disabled, so they will not be in the form data).

As a side effect, this removes the fields from changed_data too.

Parameters:cleaned_data (dict) – Cleaned data
Returns:Cleaned data without protected field data
Return type:dict
clean()[source]
shoop.core.utils.maintenance module
shoop.core.utils.maintenance.maintenance_mode_exempt(view_func)[source]

Make view ignore shop maintenance mode

Parameters:view_func – view attached to this decorator
Returns:view added with maintenance_mode_exempt attribute
shoop.core.utils.model_caching_descriptor module
class shoop.core.utils.model_caching_descriptor.ModelCachingDescriptor(name, queryset)[source]

Bases: object

set_id(instance, value)[source]
get_id(instance)[source]
set_object(instance, value)[source]
get_object(instance)[source]
shoop.core.utils.name_mixin module
class shoop.core.utils.name_mixin.NameMixin[source]

Bases: object

split_name
first_name
last_name
full_name
shoop.core.utils.product_caching_object module
class shoop.core.utils.product_caching_object.ProductCachingObject[source]

Bases: object

product
product_id
shoop.core.utils.query module
shoop.core.utils.query.group_by_period(queryset, column, period, **annotate)[source]

Group and annotate given queryset by a given date period.

Parameters:
  • queryset (django.db.QuerySet) – Original queryset
  • column (str) – Column for grouping
  • period (str) – Period for grouping (‘year’, ‘month’, ‘day’)
  • annotate (dict[str,str]) – Dict for annotate()
Returns:

OrderedDict of period -> annotate columns

Return type:

collections.OrderedDict

shoop.core.utils.slugs module
shoop.core.utils.slugs.generate_multilanguage_slugs(object, name_getter, slug_length=128)[source]
shoop.core.utils.tax_numbers module
shoop.core.utils.tax_numbers.validate(tax_number)[source]

Validate a tax number.

Parameters:tax_number (str) – Tax number to validate
Returns:Type identifier of the tax number, if detected. Possible values for now are either “vat” or “unknown”.
Return type:str
Raise:ValidationError if tax number type was detected, but it is somehow malformed.
shoop.core.utils.users module
shoop.core.utils.users.real_user_or_none(user)[source]

Convert anonymous user to None.

If user is anonymous, return None, otherwise return the user as is.

shoop.core.utils.vat module
shoop.core.utils.vat.compile_pattern(prefix, pattern)[source]
exception shoop.core.utils.vat.VatValidationError(*args, **kwargs)[source]

Bases: django.core.exceptions.ValidationError

code = None
exception shoop.core.utils.vat.VatCannotIdentifyValidationError(*args, **kwargs)[source]

Bases: shoop.core.utils.vat.VatValidationError

code = 'vat_cannot_identify'
exception shoop.core.utils.vat.VatInvalidValidationError(*args, **kwargs)[source]

Bases: shoop.core.utils.vat.VatValidationError

code = 'vat_invalid'
shoop.core.utils.vat.verify_vat(vat_id, default_prefix='')[source]

Verify an EU VAT ID.

Returns a tuple (prefix, code_parts) – if both are truthy, the validation succeeded. If the prefix part is falsy, then the prefix was unknown and no validation was even attempted. If the prefix part is truthy, then it will contain the country prefix used for validation. The code_parts part can still be falsy, if the validation for the country’s VAT number pattern failed.

Parameters:
  • vat_id (str) – The VAT ID string to validate.
  • default_prefix (str) – The default prefix to assume if none can be parsed.
Returns:

Tuple of (prefix, code_parts)

shoop.core.utils.vat.get_vat_prefix_for_country(iso3166)[source]
Module contents
Submodules
shoop.core.excs module
exception shoop.core.excs.ImmutabilityError[source]

Bases: ValueError

exception shoop.core.excs.NoProductsToShipException[source]

Bases: Exception

exception shoop.core.excs.NoPaymentToCreateException[source]

Bases: Exception

exception shoop.core.excs.ProductNotOrderableProblem(message, title=None)[source]

Bases: shoop.utils.excs.Problem

exception shoop.core.excs.ProductNotVisibleProblem(message, title=None)[source]

Bases: shoop.utils.excs.Problem

exception shoop.core.excs.ImpossibleProductModeException(message, code=None)[source]

Bases: ValueError

shoop.core.middleware module
class shoop.core.middleware.ExceptionMiddleware[source]

Bases: object

process_exception(request, exception)[source]
shoop.core.settings module
shoop.core.settings.SHOOP_HOME_CURRENCY = 'EUR'

The home currency for the Shoop installation. All monetary values are implicitly in this currency unless somehow otherwise specified.

shoop.core.settings.SHOOP_ADDRESS_HOME_COUNTRY = None

The home country code (ISO 3166-1 alpha 2) for the Shoop installation. Among other things, addresses that would be printed with this country visible are printed with no country.

shoop.core.settings.SHOOP_ALLOW_ANONYMOUS_ORDERS = True

Whether or not anonymous orders (without a creator user) are allowed.

shoop.core.settings.SHOOP_ORDER_IDENTIFIER_METHOD = 'id'

Which method is used to calculate order identifiers (“order numbers”). May be either the string “id”, a callable or a spec string pointing to a callable that must return a string given an order.

shoop.core.settings.SHOOP_REFERENCE_NUMBER_METHOD = 'unique'

Which method is used to calculate order reference numbers.

May be a spec string pointing to a callable that must return a string given an Order, or one of the following built-in generators.

unique
Unique reference number based on time and the order ID. The reference number has the Finnish bank reference check digit appended, making the reference number valid for Finnish bank transfers.
running
Ascending reference number. The length of the reference number will be SHOOP_REFERENCE_NUMBER_LENGTH + 1 (for the check digit described below). SHOOP_REFERENCE_NUMBER_PREFIX is prepended, if set. The reference number has the Finnish bank reference check digit appended, making the reference number valid for Finnish bank transfers.
shop_running
As running, but with the shop ID prepended.
shoop.core.settings.SHOOP_REFERENCE_NUMBER_LENGTH = 10

The length of reference numbers generated by certain reference number generators.

shoop.core.settings.SHOOP_REFERENCE_NUMBER_PREFIX = ''

An arbitrary (numeric) prefix for certain reference number generators.

shoop.core.settings.SHOOP_PRICING_MODULE = 'simple_pricing'

The identifier of the pricing module to use for pricing products.

Determines how product prices are calculated. See shoop.core.pricing for details.

shoop.core.settings.SHOOP_TAX_MODULE = 'default_tax'

The identifier of the tax module to use for determining taxes of products and order lines.

Determines taxing rules for products, shipping/payment methods and other order lines. See shoop.core.taxing for details.

shoop.core.settings.SHOOP_ENABLE_ATTRIBUTES = True

Whether product attributes are enabled. For installations not requiring attributes, disabling this may confer a small performance increase.

shoop.core.settings.SHOOP_ENABLE_MULTIPLE_SHOPS = False

Whether multiple shops are expected to be enabled in this installation. Enabling or disabling this flag does not make it (im)possible to set up multiple shops, but having it disabled may confer a small performance increase.

shoop.core.settings.SHOOP_ORDER_LABELS = [('default', 'Default')]

A list of order labels (2-tuples of internal identifier / visible name).

Order labels serve as a simple taxonomy layer for easy “tagging” of orders even within a single Shop. For instance, an installation could define "default" and "internal" order labels, which are then usable in reports, admin filtering, etc.

shoop.core.settings.SHOOP_DEFAULT_ORDER_LABEL = 'default'

The order label (see SHOOP_ORDER_LABELS) to apply to orders by default. This should naturally be one of the keys in SHOOP_ORDER_LABELS.

shoop.core.settings.SHOOP_ORDER_KNOWN_PAYMENT_DATA_KEYS = []

A list of “known keys” within the Order.payment_data property bag.

The format of this setting is a list of 2-tuples of dict key / visible name, for example [("ssn", "Social Security Number")].

For installations where customizations may save some human-readable, possibly important information in payment_data, this setting may be used to make this data easily visible in the administration backend.

shoop.core.settings.SHOOP_ORDER_KNOWN_SHIPPING_DATA_KEYS = []

A list of “known keys” within the Order.shipping_data property bag.

The format of this setting is a list of 2-tuples of dict key / visible name, for example [("shipping_instruction", "Special Shipping Instructions")].

For installations where customizations may save some human-readable, possibly important information in shipping_data, this setting may be used to make this data easily visible in the administration backend.

shoop.core.settings.SHOOP_ORDER_KNOWN_EXTRA_DATA_KEYS = []

A list of “known keys” within the Order.extra_data property bag.

The format of this setting is a list of 2-tuples of dict key / visible name, for example [("wrapping_color", "Wrapping Paper Color")].

For installations where customizations may save some human-readable, possibly important information in extra_data, this setting may be used to make this data easily visible in the administration backend.

shoop.core.settings.SHOOP_TELEMETRY_ENABLED = True

A flag to enable/disable the telemetry system

shoop.core.settings.SHOOP_TELEMETRY_URL = 'https://telemetry.shoop.io/collect/'

The submission URL for Shoop’s telemetry (statistics) system

shoop.core.settings.SHOOP_DEFAULT_CACHE_DURATION = 1800

Default cache duration for various caches in seconds

shoop.core.settings.SHOOP_CACHE_DURATIONS = {}

Overrides for default cache durations by key namespace. These override possible defaults in shoop.core.cache.impl.DEFAULT_CACHE_DURATIONS.

shoop.core.signals module
shoop.core.telemetry module
shoop.core.telemetry.safe_json(data_dict, indent=None)[source]
shoop.core.telemetry.get_installation_key()[source]

Get the unique installation ID for this Shoop instance.

If one doesn’t exist, it’s generated and saved at this point.

Returns:Installation key string
Return type:str
shoop.core.telemetry.is_opt_out()[source]
shoop.core.telemetry.is_in_grace_period()[source]

Return True if the telemetry module is within the 24-hours-from-installation grace period where no stats are sent. This is to “safely” allow opting out of telemetry without leaving a trace.

Returns:Graceness flag.
Return type:bool
shoop.core.telemetry.is_telemetry_enabled()[source]
shoop.core.telemetry.set_opt_out(flag)[source]

Set whether this installation is opted-out from telemetry submissions.

Parameters:flag (bool) – Opt-out flag. True for opt-out, false for opt-in (default)
Returns:New flag state
Return type:bool
shoop.core.telemetry.get_last_submission_time()[source]
shoop.core.telemetry.get_last_submission_data()[source]
shoop.core.telemetry.save_telemetry_submission(data)[source]

Save a blob of data as the latest telemetry submission.

Naturally updates the latest submission time.

Parameters:data (dict) – A blob of data.
shoop.core.telemetry.get_telemetry_data(request, indent=None)[source]

Get the telemetry data that would be sent.

Parameters:request (django.http.HttpRequest|None) – HTTP request. Optional.
Returns:Data blob.
Return type:str
exception shoop.core.telemetry.TelemetryNotSent(message, code)[source]

Bases: Exception

shoop.core.telemetry.try_send_telemetry(request=None, max_age_hours=72, raise_on_error=False)[source]

Send telemetry information (unless opted-out, in grace period or disabled).

Parameters:
  • request (django.http.HttpRequest|None) – HTTP request. Optional.
  • max_age_hours (int|None) – How many hours must have passed since the last submission to be able to resend. If None, not checked.
  • raise_on_error (bool) – Raise exceptions when telemetry is not sent instead of quietly returning False.
Returns:

Sent data (possibly with response information) or False if not sent.

Return type:

dict|bool

Module contents
class shoop.core.ShoopCoreAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.core'
verbose_name = 'Shoop Core'
label = 'shoop'
required_installed_apps = ('django.contrib.auth', 'django.contrib.contenttypes', 'easy_thumbnails', 'filer')
provides = {'pricing_module': ['shoop.core.pricing.default_pricing:DefaultPricingModule'], 'api_populator': ['shoop.core.api:populate_core_api']}
shoop.default_tax package
Subpackages
shoop.default_tax.admin_module package
Submodules
shoop.default_tax.admin_module.views module
class shoop.default_tax.admin_module.views.TaxRuleForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of TaxRule

fields = ['tax_classes', 'customer_tax_groups', 'country_codes_pattern', 'region_codes_pattern', 'postal_codes_pattern', 'priority', 'override_group', 'tax', 'enabled']
help_texts = {'region_codes_pattern': <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f65582682b0>, 'postal_codes_pattern': <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655cf3b2e8>, 'country_codes_pattern': <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f6558268710>}
TaxRuleForm.clean()[source]
TaxRuleForm.base_fields = OrderedDict([('tax_classes', <django.forms.models.ModelMultipleChoiceField object at 0x7f6558268400>), ('customer_tax_groups', <django.forms.models.ModelMultipleChoiceField object at 0x7f6558a35eb8>), ('country_codes_pattern', <django.forms.fields.CharField object at 0x7f655843d940>), ('region_codes_pattern', <django.forms.fields.CharField object at 0x7f655843d6a0>), ('postal_codes_pattern', <django.forms.fields.CharField object at 0x7f655843deb8>), ('priority', <django.forms.fields.IntegerField object at 0x7f655843de10>), ('override_group', <django.forms.fields.IntegerField object at 0x7f655843d0b8>), ('tax', <django.forms.models.ModelChoiceField object at 0x7f655843d978>), ('enabled', <django.forms.fields.BooleanField object at 0x7f6558268f60>)])
TaxRuleForm.declared_fields = OrderedDict()
TaxRuleForm.media
class shoop.default_tax.admin_module.views.TaxRuleEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of TaxRule

template_name = 'shoop/default_tax/admin/edit.jinja'
form_class

alias of TaxRuleForm

context_object_name = 'tax_rule'
add_form_errors_as_messages = True
class shoop.default_tax.admin_module.views.TaxRuleListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of TaxRule

columns = [<shoop.admin.utils.picotable.Column object at 0x7f655843d358>, <shoop.admin.utils.picotable.Column object at 0x7f655843d4a8>, <shoop.admin.utils.picotable.Column object at 0x7f655843dc18>, <shoop.admin.utils.picotable.Column object at 0x7f65581d0cf8>, <shoop.admin.utils.picotable.Column object at 0x7f65581d0c18>, <shoop.admin.utils.picotable.Column object at 0x7f65581d0e10>, <shoop.admin.utils.picotable.Column object at 0x7f65581d01d0>, <shoop.admin.utils.picotable.Column object at 0x7f65581d0828>, <shoop.admin.utils.picotable.Column object at 0x7f65581d0fd0>, <shoop.admin.utils.picotable.Column object at 0x7f655807c320>]
Module contents
class shoop.default_tax.admin_module.TaxRulesAdminModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
Submodules
shoop.default_tax.models module
class shoop.default_tax.models.TaxRule(id, enabled, country_codes_pattern, region_codes_pattern, postal_codes_pattern, priority, override_group, tax)[source]

Bases: django.db.models.base.Model

tax_classes
customer_tax_groups
tax
matches(taxing_context)[source]

Check if this tax rule matches given taxing context.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception TaxRule.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

TaxRule.objects = <django.db.models.manager.Manager object>
shoop.default_tax.module module
class shoop.default_tax.module.DefaultTaxModule[source]

Bases: shoop.core.taxing.TaxModule

identifier = 'default_tax'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_taxed_price_for(context, item, price)[source]
shoop.default_tax.module.get_taxes_of_effective_rules(taxing_context, tax_rules)[source]

Get taxes grouped by priority from effective tax rules.

Effective tax rules is determined by first limiting the scope to the rules that match the given taxing context (see TaxRule.match) and then further limiting the matching rules by selecting only the rules in the highest numbered override group.

The Tax objects in the effective rules will be grouped by the priority of the rules. The tax groups are returned as list of tax lists.

Parameters:tax_rules (Iterable[TaxRule]) – Tax rules to filter from. These should be ordered desceding by override group and then ascending by priority.
Return type:list[list[shoop.core.models.Tax]]
Module contents
class shoop.default_tax.AppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.default_tax'
verbose_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
label = 'default_tax'
provides = {'admin_module': ['shoop.default_tax.admin_module:TaxRulesAdminModule'], 'tax_module': ['shoop.default_tax.module:DefaultTaxModule']}
shoop.discount_pricing package
Submodules
shoop.discount_pricing.admin_form_part module
class shoop.discount_pricing.admin_form_part.DiscountPricingForm(**kwargs)[source]

Bases: django.forms.forms.Form

save()[source]
get_shop_field(shop)[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.discount_pricing.admin_form_part.DiscountPricingFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = 10
get_form_defs()[source]
form_valid(form)[source]
shoop.discount_pricing.models module
class shoop.discount_pricing.models.DiscountedProductPrice(id, product, shop, price_value)[source]

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

product
shop
price

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception DiscountedProductPrice.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

DiscountedProductPrice.objects = <django.db.models.manager.Manager object>
shoop.discount_pricing.module module

Discount Pricing Module.

This module handles basic discounts for products.

If the discounted price is higher than the default_price, the lower will be used.

Example:

If default_price is 50 and discounted price is 20, the effective product price will be 20.
class shoop.discount_pricing.module.DiscountPricingContext(**kwargs)[source]

Bases: shoop.core.pricing.PricingContext

REQUIRED_VALUES = ['shop']
shop = None
class shoop.discount_pricing.module.DiscountPricingModule[source]

Bases: shoop.core.pricing.PricingModule

identifier = 'discount_pricing'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
pricing_context_class

alias of DiscountPricingContext

get_context_from_request(request)[source]
get_price_info(context, product, quantity=1)[source]
Module contents
class shoop.discount_pricing.DiscountPricingAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.discount_pricing'
verbose_name = 'Shoop Discount Pricing'
label = 'discount_pricing'
provides = {'pricing_module': ['shoop.discount_pricing.module:DiscountPricingModule'], 'admin_product_form_part': ['shoop.discount_pricing.admin_form_part:DiscountPricingFormPart']}
shoop.front package
Subpackages
shoop.front.apps package
Subpackages
shoop.front.apps.auth package
Submodules
shoop.front.apps.auth.forms module
class shoop.front.apps.auth.forms.EmailAuthenticationForm(*args, **kwargs)[source]

Bases: django.contrib.auth.forms.AuthenticationForm

error_messages = {'inactive': 'This account is inactive.', 'invalid_login': 'Please enter a correct %(username)s and password. Note that both fields may be case-sensitive. In case of multiple accounts with same email only username can be used to login.'}
clean_username()[source]
base_fields = OrderedDict([('username', <django.forms.fields.CharField object at 0x7f655ce5f9b0>), ('password', <django.forms.fields.CharField object at 0x7f655ce5f9e8>)])
declared_fields = OrderedDict([('username', <django.forms.fields.CharField object at 0x7f655ce5f9b0>), ('password', <django.forms.fields.CharField object at 0x7f655ce5f9e8>)])
media
class shoop.front.apps.auth.forms.RecoverPasswordForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

token_generator = <django.contrib.auth.tokens.PasswordResetTokenGenerator object>
subject_template_name = ('shoop/user/recover_password_mail_subject.jinja',)
email_template_name = 'shoop/user/recover_password_mail_content.jinja'
from_email = None
clean()[source]
save(request)[source]
process_user(user_to_recover)[source]
base_fields = OrderedDict([('username', <django.forms.fields.CharField object at 0x7f655ca79860>), ('email', <django.forms.fields.EmailField object at 0x7f655ca79978>)])
declared_fields = OrderedDict([('username', <django.forms.fields.CharField object at 0x7f655ca79860>), ('email', <django.forms.fields.EmailField object at 0x7f655ca79978>)])
media
shoop.front.apps.auth.urls module
shoop.front.apps.auth.views module
class shoop.front.apps.auth.views.LoginView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/login.jinja'
form_class

alias of EmailAuthenticationForm

get_form(form_class=None)[source]
form_valid(form)[source]
get_success_url()[source]
class shoop.front.apps.auth.views.LogoutView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/logout.jinja'
dispatch(request, *args, **kwargs)[source]
class shoop.front.apps.auth.views.RecoverPasswordView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/recover_password.jinja'
form_class

alias of RecoverPasswordForm

success_url = <django.utils.functional.lazy.<locals>.__proxy__ object>
form_valid(form)[source]
class shoop.front.apps.auth.views.RecoverPasswordConfirmView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/recover_password_confirm.jinja'
form_class

alias of SetPasswordForm

token_generator = <django.contrib.auth.tokens.PasswordResetTokenGenerator object>
success_url = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_form_kwargs()[source]
get_target_user()[source]
dispatch(request, *args, **kwargs)[source]
form_valid(form)[source]
class shoop.front.apps.auth.views.RecoverPasswordSentView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/recover_password_sent.jinja'
class shoop.front.apps.auth.views.RecoverPasswordCompleteView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/user/recover_password_complete.jinja'
Module contents
class shoop.front.apps.auth.AuthAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front.apps.auth'
verbose_name = 'Shoop Frontend - User Authentication'
label = 'shoop_front.auth'
provides = {'front_urls': ['shoop.front.apps.auth.urls:urlpatterns']}
shoop.front.apps.customer_information package
Submodules
shoop.front.apps.customer_information.urls module
shoop.front.apps.customer_information.views module
class shoop.front.apps.customer_information.views.PersonContactForm(*args, **kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of PersonContact

fields = ('name', 'phone', 'email', 'gender', 'marketing_permission')
PersonContactForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655ca05550>), ('phone', <django.forms.fields.CharField object at 0x7f655ca053c8>), ('email', <django.forms.fields.EmailField object at 0x7f655ca05710>), ('gender', <enumfields.forms.EnumChoiceField object at 0x7f655ca05898>), ('marketing_permission', <django.forms.fields.BooleanField object at 0x7f655ca052e8>)])
PersonContactForm.declared_fields = OrderedDict()
PersonContactForm.media
class shoop.front.apps.customer_information.views.AddressForm(*args, **kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of MutableAddress

fields = ('name', 'phone', 'email', 'street', 'street2', 'postal_code', 'city', 'region', 'country')
AddressForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f655ca05a58>), ('phone', <django.forms.fields.CharField object at 0x7f655ca05be0>), ('email', <django.forms.fields.EmailField object at 0x7f655ca05da0>), ('street', <django.forms.fields.CharField object at 0x7f655ca05ef0>), ('street2', <django.forms.fields.CharField object at 0x7f655ca080b8>), ('postal_code', <django.forms.fields.CharField object at 0x7f655ca08240>), ('city', <django.forms.fields.CharField object at 0x7f655ca083c8>), ('region', <django.forms.fields.CharField object at 0x7f655ca08550>), ('country', <django_countries.fields.LazyTypedChoiceField object at 0x7f655ca08710>)])
AddressForm.declared_fields = OrderedDict()
AddressForm.media
class shoop.front.apps.customer_information.views.CustomerEditView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/customer_information/edit.jinja'
get_form(form_class=None)
form_valid(form)[source]
Module contents
class shoop.front.apps.customer_information.AppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front.apps.customer_information'
verbose_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
label = 'shoop_front.customer_information'
provides = {'front_urls': ['shoop.front.apps.customer_information.urls:urlpatterns']}
shoop.front.apps.personal_order_history package
Submodules
shoop.front.apps.personal_order_history.urls module
shoop.front.apps.personal_order_history.views module
class shoop.front.apps.personal_order_history.views.OrderViewMixin[source]

Bases: object

model

alias of Order

get_queryset()[source]
class shoop.front.apps.personal_order_history.views.OrderListView(**kwargs)[source]

Bases: shoop.front.apps.personal_order_history.views.OrderViewMixin, django.views.generic.list.ListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/personal_order_history/order_list.jinja'
context_object_name = 'orders'
class shoop.front.apps.personal_order_history.views.OrderDetailView(**kwargs)[source]

Bases: shoop.front.apps.personal_order_history.views.OrderViewMixin, django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/personal_order_history/order_detail.jinja'
context_object_name = 'order'
Module contents
class shoop.front.apps.personal_order_history.AppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front.apps.personal_order_history'
verbose_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
label = 'shoop_front.personal_order_history'
provides = {'front_urls': ['shoop.front.apps.personal_order_history.urls:urlpatterns']}
shoop.front.apps.registration package
Submodules
shoop.front.apps.registration.settings module
shoop.front.apps.registration.settings.SHOOP_REGISTRATION_REQUIRES_ACTIVATION = True

Require email-based activation for users?

This corresponds to using the default or simple django-registration backends.

shoop.front.apps.registration.urls module
shoop.front.apps.registration.views module
shoop.front.apps.registration.views.activation_complete(request)[source]
shoop.front.apps.registration.views.registration_complete(request)[source]
class shoop.front.apps.registration.views.RegistrationViewMixin[source]

Bases: object

template_name = 'shoop/registration/register.jinja'
get_success_url(request, user)[source]
class shoop.front.apps.registration.views.RegistrationNoActivationView(**kwargs)[source]

Bases: shoop.front.apps.registration.views.RegistrationViewMixin, registration.backends.simple.views.RegistrationView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class shoop.front.apps.registration.views.RegistrationWithActivationView(**kwargs)[source]

Bases: shoop.front.apps.registration.views.RegistrationViewMixin, registration.backends.default.views.RegistrationView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class shoop.front.apps.registration.views.RegistrationView(**kwargs)[source]

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

dispatch(request, *args, **kwargs)[source]
class shoop.front.apps.registration.views.ActivationView(**kwargs)[source]

Bases: registration.backends.default.views.ActivationView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/registration/activation_failed.jinja'
get_success_url(request, user)[source]
Module contents
Shoop Registration Add-on

The shoop.front.apps.registration add-on provides simple user registration and email token based activation.

It is based on the django-registration-redux package.

Installation

Add registration and shoop.front.apps.registration into your INSTALLED_APPS (and run migrations, of course).

The application registers its URLs via the front_urls provides mechanism.

URL names
  • shoop:registration_register – the entry point for registration.
class shoop.front.apps.registration.RegistrationAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front.apps.registration'
verbose_name = 'Shoop Frontend - User Registration'
label = 'shoop_front.registration'
required_installed_apps = {'registration': 'django-registration-redux is required for user registration and activation'}
provides = {'front_urls': ['shoop.front.apps.registration.urls:urlpatterns']}
ready()[source]
shoop.front.apps.simple_order_notification package
Subpackages
shoop.front.apps.simple_order_notification.admin_module package
Module contents
class shoop.front.apps.simple_order_notification.admin_module.SimpleOrderNotificationModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
category = <django.utils.functional.lazy.<locals>.__proxy__ object>
get_notifications(request)[source]
Submodules
shoop.front.apps.simple_order_notification.templates module
Module contents
shoop.front.apps.simple_order_notification.send_simple_order_notification(sender, order, request, **kwargs)[source]
Parameters:order (shoop.core.models.Order) – Order
class shoop.front.apps.simple_order_notification.SimpleOrderNotificationAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front.apps.simple_order_notification'
verbose_name = 'Shoop Frontend - Simple Order Notification'
label = 'shoop_front.simple_order_notification'
provides = {'admin_module': ['shoop.front.apps.simple_order_notification.admin_module:SimpleOrderNotificationModule']}
ready()[source]
shoop.front.apps.simple_search package
Submodules
shoop.front.apps.simple_search.template_helpers module
class shoop.front.apps.simple_search.template_helpers.TemplateHelpers[source]

Bases: object

name = 'simple_search'
get_search_form(context, template_name='shoop/simple_search/search_form.jinja')[source]

Get a product search form, usable e.g. for navigation bars. The q request parameter is used by default to pre-fill the search query field. The name of the template rendered can be overridden with the template_name parameter.

Parameters:
  • context (jinja2.runtime.Context) – Template context
  • template_name (str) – Template file name
shoop.front.apps.simple_search.urls module
shoop.front.apps.simple_search.views module
shoop.front.apps.simple_search.views.get_search_product_ids(request, query)[source]
class shoop.front.apps.simple_search.views.SearchForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

clean()[source]
base_fields = OrderedDict([('q', <django.forms.fields.CharField object at 0x7f655ca27be0>), ('sort', <django.forms.fields.CharField object at 0x7f655ca1e390>)])
declared_fields = OrderedDict([('q', <django.forms.fields.CharField object at 0x7f655ca27be0>), ('sort', <django.forms.fields.CharField object at 0x7f655ca1e390>)])
media
class shoop.front.apps.simple_search.views.SearchView(**kwargs)[source]

Bases: django.views.generic.list.ListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of SearchForm

template_name = 'shoop/simple_search/search.jinja'
model

alias of Product

context_object_name = 'products'
dispatch(request, *args, **kwargs)[source]
get_queryset()[source]
get_context_data(**kwargs)[source]
Module contents
shoop.front.basket package
Submodules
shoop.front.basket.command_dispatcher module
class shoop.front.basket.command_dispatcher.BasketCommandDispatcher(request, basket=None)[source]

Bases: object

BasketCommandDispatcher handles (usually AJAX) requests that somehow update the basket. You should never instantiate BasketCommandDispatcher yourself – instead use get_basket_command_dispatcher().

All handle_* methods are expected to accept **kwargs.

commands_module = <module 'shoop.front.basket.commands' from '/home/docs/checkouts/readthedocs.org/user_builds/shoop/checkouts/v3.0.0/doc/../shoop/front/basket/commands.py'>
get_command_handler(command)[source]
handle(command, kwargs=None)[source]

Dispatch and handle processing of the given command.

Parameters:
  • command (unicode) – Name of command to run
  • kwargs (dict) – Arguments to pass to the command handler. If empty, request.POST is used.
Returns:

response

Return type:

HttpResponse

preprocess_kwargs(command, kwargs)[source]

Preprocess kwargs before they are passed to the given command handler. Useful for subclassing. Must return the new kwargs, even if it wasn’t mutated.

Parameters:
  • command – The name of the command about to be run
  • kwargs – dict of arguments
Returns:

dict of arguments

postprocess_response(command, kwargs, response)[source]

Postprocess the response dictionary (not a HTTP response!) before it is either turned into JSON or otherwise processed (in the case of non-AJAX requests).

Parameters:
  • command – The command that was run.
  • kwargs – The actual kwargs the command was run with.
  • response – The response the command returned.
Returns:

The response to be processed and sent to the client.

shoop.front.basket.commands module
shoop.front.basket.commands.handle_add(request, basket, product_id, quantity=1, supplier_id=None, **kwargs)[source]

Handle adding a product to the basket.

Parameters:
  • product_id – product ID to add (or if child_product_id is truey, the parent ID)
  • quantity – quantity of products to add
  • child_product_id – child product ID to add (if truey)
  • supplier_id – The supplier ID for the new line. If None, the first supplier is used.
shoop.front.basket.commands.handle_add_var(request, basket, product_id, quantity=1, **kwargs)[source]

Handle adding a complex variable product into the basket by resolving the combination variables. This actually uses kwargs, expecting var_XXX=YYY to exist there, where XXX is the PK of a ProductVariationVariable and YYY is the PK of a ProductVariationVariableValue. Confused yet?

Parameters:
  • quantity – Quantity of the resolved variation to add.
  • kwargs – Expected to contain var_* values, see above.
shoop.front.basket.commands.handle_del(request, basket, line_id, **kwargs)[source]

Handle deleting a distinct order line from the basket given its unique line ID.

Parameters:line_id – The line ID to delete.
Returns:
shoop.front.basket.commands.handle_clear(request, basket, **kwargs)[source]

Handle fully clearing the basket.

shoop.front.basket.commands.handle_update(request, basket, **kwargs)[source]

Handle updating a basket, i.e. deleting some lines or updating quantities.

This dispatches further to whatever is declared by the SHOOP_BASKET_UPDATE_METHODS_SPEC configuration entry.

shoop.front.basket.objects module
class shoop.front.basket.objects.BasketLine(source=None, **kwargs)[source]

Bases: shoop.core.order_creator._source.SourceLine

shop_product

ShopProduct object of this line.

Return type:shoop.core.models.ShopProduct
cache_info(request)[source]
type
set_quantity(quantity)[source]
can_delete
can_change_quantity
class shoop.front.basket.objects.BaseBasket(request, basket_name='basket')[source]

Bases: shoop.core.order_creator._source.OrderSource

save()[source]

Persist any changes made into the basket to storage.

One does not usually need to directly call this; ShoopFrontMiddleware will usually take care of it.

delete()[source]

Clear and delete the basket data.

finalize()[source]

Mark the basket as “completed” (i.e. an order is created/a conversion made).

This will also clear the basket’s data.

clear_all()[source]

Clear all data for this basket.

add_line(**kwargs)[source]
get_lines()[source]
clean_empty_lines()[source]
add_product(supplier, shop, product, quantity, force_new_line=False, extra=None, parent_line=None)[source]
update_line(data_line, **kwargs)[source]
add_product_with_child_product(supplier, shop, product, child_product, quantity)[source]
delete_line(line_id)[source]
find_line_by_line_id(line_id)[source]
find_lines_by_parent_line_id(parent_line_id)[source]
orderable
get_validation_errors()[source]
get_product_ids_and_quantities()[source]
get_available_shipping_methods()[source]

Get available shipping methods.

Return type:list[ShippingMethod]
get_available_payment_methods()[source]

Get available payment methods.

Return type:list[PaymentMethod]
product_ids
total_weight
product_count
is_empty
shoop.front.basket.order_creator module
class shoop.front.basket.order_creator.BasketOrderCreator(request)[source]

Bases: shoop.core.order_creator._creator.OrderCreator

shoop.front.basket.storage module
exception shoop.front.basket.storage.BasketCompatibilityError[source]

Bases: Exception

exception shoop.front.basket.storage.ShopMismatchBasketCompatibilityError[source]

Bases: shoop.front.basket.storage.BasketCompatibilityError

exception shoop.front.basket.storage.PriceUnitMismatchBasketCompatibilityError[source]

Bases: shoop.front.basket.storage.BasketCompatibilityError

class shoop.front.basket.storage.BasketStorage[source]

Bases: object

load(basket)[source]

Load the given basket’s data dictionary from the storage.

Return type:dict
Raises:BasketCompatibilityError if basket loaded from the storage is not compatible with the requested basket.
save(basket, data)[source]

Save the given data dictionary into the storage for the given basket.

delete(basket)[source]

Delete the basket from storage.

finalize(basket)[source]

Mark the basket as “finalized” (i.e. completed) in the storage.

The actual semantics of what finalization does are up to each backend.

class shoop.front.basket.storage.DirectSessionBasketStorage[source]

Bases: shoop.front.basket.storage.BasketStorage

save(basket, data)[source]
delete(basket)[source]
class shoop.front.basket.storage.DictStoredBasket(id, shop_id, currency, prices_include_tax, data)[source]

Bases: object

classmethod from_basket_and_data(basket, data)[source]
classmethod from_dict(mapping)[source]
as_dict()[source]
class shoop.front.basket.storage.DatabaseBasketStorage[source]

Bases: shoop.front.basket.storage.BasketStorage

save(basket, data)[source]
delete(basket)[source]
finalize(basket)[source]
shoop.front.basket.storage.get_storage()[source]

Retrieve a basket storage object.

Returns:A basket storage object
Return type:BasketStorage
shoop.front.basket.update_methods module
class shoop.front.basket.update_methods.BasketUpdateMethods(request, basket)[source]

Bases: object

get_prefix_to_method_map()[source]

Override this method to link prefixes with their associated methods to call.

Format of the dictionary is: { FIELD_NAME_PREFIX: METHOD }.

METHOD is a function which accepts the keyword arguments given in update_basket_contents. It should perform the necessary changes to the basket_line and then return whether the value had changed or not. (See update_quantity or delete_line for examples.)

delete_line(line, **kwargs)[source]
update_quantity(line, value, **kwargs)[source]
Module contents
shoop.front.basket.get_basket_order_creator(request)[source]
shoop.front.basket.get_basket_view()[source]
shoop.front.basket.get_basket_command_dispatcher(request)[source]
Return type:shoop.front.basket.command_dispatcher.BasketCommandDispatcher
shoop.front.basket.get_basket(request)[source]
Return type:shoop.front.basket.objects.BaseBasket
shoop.front.checkout package
Submodules
shoop.front.checkout.addresses module
class shoop.front.checkout.addresses.AddressForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of MutableAddress

fields = ('name', 'phone', 'email', 'street', 'street2', 'postal_code', 'city', 'region', 'country')
AddressForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f6558404710>), ('phone', <django.forms.fields.CharField object at 0x7f65578c8a58>), ('email', <django.forms.fields.EmailField object at 0x7f6557854978>), ('street', <django.forms.fields.CharField object at 0x7f65578541d0>), ('street2', <django.forms.fields.CharField object at 0x7f655781b2b0>), ('postal_code', <django.forms.fields.CharField object at 0x7f655781bd30>), ('city', <django.forms.fields.CharField object at 0x7f65578a4ba8>), ('region', <django.forms.fields.CharField object at 0x7f6557817470>), ('country', <django_countries.fields.LazyTypedChoiceField object at 0x7f65578176a0>)])
AddressForm.declared_fields = OrderedDict()
AddressForm.media
class shoop.front.checkout.addresses.CompanyForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None)[source]

Bases: shoop.front.checkout._mixins.TaxNumberCleanMixin, django.forms.models.ModelForm

company_name_field = 'name'
class Meta[source]

Bases: object

model

alias of CompanyContact

fields = ('name', 'tax_number')
CompanyForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f65578174e0>), ('tax_number', <django.forms.fields.CharField object at 0x7f65578173c8>)])
CompanyForm.declared_fields = OrderedDict()
CompanyForm.media
class shoop.front.checkout.addresses.AddressesPhase(**kwargs)[source]

Bases: shoop.front.checkout.CheckoutPhaseViewMixin, django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'addresses'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
template_name = 'shoop/front/checkout/addresses.jinja'
address_kinds = ('shipping', 'billing')
address_form_class

alias of AddressForm

address_form_classes = {}
company_form_class

alias of CompanyForm

get_form(form_class=None)
get_initial()[source]
is_valid()[source]
form_valid(form)[source]
process()[source]
shoop.front.checkout.confirm module
class shoop.front.checkout.confirm.ConfirmForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

base_fields = OrderedDict([('accept_terms', <django.forms.fields.BooleanField object at 0x7f65578081d0>), ('marketing', <django.forms.fields.BooleanField object at 0x7f6557808278>), ('comment', <django.forms.fields.CharField object at 0x7f6557808358>)])
declared_fields = OrderedDict([('accept_terms', <django.forms.fields.BooleanField object at 0x7f65578081d0>), ('marketing', <django.forms.fields.BooleanField object at 0x7f6557808278>), ('comment', <django.forms.fields.CharField object at 0x7f6557808358>)])
media
class shoop.front.checkout.confirm.ConfirmPhase(**kwargs)[source]

Bases: shoop.front.checkout.CheckoutPhaseViewMixin, django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'confirm'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
template_name = 'shoop/front/checkout/confirm.jinja'
form_class

alias of ConfirmForm

process()[source]
is_valid()[source]
get_context_data(**kwargs)[source]
form_valid(form)[source]
create_order()[source]
shoop.front.checkout.empty module
class shoop.front.checkout.empty.EmptyPhase(**kwargs)[source]

Bases: shoop.front.checkout.CheckoutPhaseViewMixin, django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'empty'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
template_name = 'shoop/front/checkout/empty.jinja'
process()[source]
shoop.front.checkout.methods module
class shoop.front.checkout.methods.MethodModelChoiceField(*args, **kwargs)[source]

Bases: django.forms.models.ModelChoiceField

label_from_instance(obj)[source]
class shoop.front.checkout.methods.MethodsForm(*args, **kwargs)[source]

Bases: django.forms.forms.Form

limit_method_fields()[source]
base_fields = OrderedDict([('shipping_method', <shoop.front.checkout.methods.MethodModelChoiceField object at 0x7f655777f358>), ('payment_method', <shoop.front.checkout.methods.MethodModelChoiceField object at 0x7f655777f518>)])
declared_fields = OrderedDict([('shipping_method', <shoop.front.checkout.methods.MethodModelChoiceField object at 0x7f655777f358>), ('payment_method', <shoop.front.checkout.methods.MethodModelChoiceField object at 0x7f655777f518>)])
media
class shoop.front.checkout.methods.MethodsPhase(**kwargs)[source]

Bases: shoop.front.checkout.CheckoutPhaseViewMixin, django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'methods'
title = <django.utils.functional.lazy.<locals>.__proxy__ object>
template_name = 'shoop/front/checkout/methods.jinja'
form_class

alias of MethodsForm

is_valid()[source]
process()[source]
get_form_kwargs()[source]
form_valid(form)[source]
get_initial()[source]
class shoop.front.checkout.methods.ShippingMethodPhase(**kwargs)[source]

Bases: shoop.front.checkout.methods._MethodDependentCheckoutPhase, django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'shipping'
get_method()[source]
class shoop.front.checkout.methods.PaymentMethodPhase(**kwargs)[source]

Bases: shoop.front.checkout.methods._MethodDependentCheckoutPhase, django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'payment'
get_method()[source]
shoop.front.checkout.single_page module
class shoop.front.checkout.single_page.AddressForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of MutableAddress

fields = ('name', 'phone', 'email', 'street', 'street2', 'postal_code', 'city', 'region', 'country')
AddressForm.base_fields = OrderedDict([('name', <django.forms.fields.CharField object at 0x7f6557742630>), ('phone', <django.forms.fields.CharField object at 0x7f6557742780>), ('email', <django.forms.fields.EmailField object at 0x7f65577428d0>), ('street', <django.forms.fields.CharField object at 0x7f65577429e8>), ('street2', <django.forms.fields.CharField object at 0x7f6557742b00>), ('postal_code', <django.forms.fields.CharField object at 0x7f6557742c18>), ('city', <django.forms.fields.CharField object at 0x7f6557742d30>), ('region', <django.forms.fields.CharField object at 0x7f6557742e48>), ('country', <django_countries.fields.LazyTypedChoiceField object at 0x7f6557742f98>)])
AddressForm.declared_fields = OrderedDict()
AddressForm.media
class shoop.front.checkout.single_page.OrderForm(*args, **kwargs)[source]

Bases: shoop.front.checkout._mixins.TaxNumberCleanMixin, django.forms.forms.Form

limit_method_fields()[source]
base_fields = OrderedDict([('company_name', <django.forms.fields.CharField object at 0x7f65576e8048>), ('tax_number', <django.forms.fields.CharField object at 0x7f65576e8160>), ('shipping_method', <shoop.utils.fields.RelaxedModelChoiceField object at 0x7f65576e8278>), ('payment_method', <shoop.utils.fields.RelaxedModelChoiceField object at 0x7f65576e8438>), ('accept_terms', <django.forms.fields.BooleanField object at 0x7f65576e85f8>), ('marketing', <django.forms.fields.BooleanField object at 0x7f65576e86a0>), ('comment', <django.forms.fields.CharField object at 0x7f65576e8780>)])
declared_fields = OrderedDict([('company_name', <django.forms.fields.CharField object at 0x7f65576e8048>), ('tax_number', <django.forms.fields.CharField object at 0x7f65576e8160>), ('shipping_method', <shoop.utils.fields.RelaxedModelChoiceField object at 0x7f65576e8278>), ('payment_method', <shoop.utils.fields.RelaxedModelChoiceField object at 0x7f65576e8438>), ('accept_terms', <django.forms.fields.BooleanField object at 0x7f65576e85f8>), ('marketing', <django.forms.fields.BooleanField object at 0x7f65576e86a0>), ('comment', <django.forms.fields.CharField object at 0x7f65576e8780>)])
media
class shoop.front.checkout.single_page.SingleCheckoutPhase(**kwargs)[source]

Bases: shoop.front.checkout.CheckoutPhaseViewMixin, django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

identifier = 'checkout'
final = True
template_name = 'shoop/front/checkout/single_phase.jinja'
billing_address_form_class

alias of AddressForm

shipping_address_form_class

alias of AddressForm

order_form_class

alias of OrderForm

get_form(form_class=None)
get_context_data(**kwargs)[source]
form_valid(form)[source]
process()[source]
Module contents
class shoop.front.checkout.CheckoutPhaseViewMixin[source]

Bases: object

identifier = None
title = None
final = False
checkout_process = None
phases = ()
next_phase = None
previous_phase = None
request = None
is_valid()[source]
should_skip()[source]
process()[source]
reset()[source]
get_success_url()[source]
storage
class shoop.front.checkout.CheckoutProcess(phase_specs, phase_kwargs)[source]

Bases: object

phases
Return type:Iterable[CheckoutPhaseViewMixin]
instantiate_phase_class(phase_class, **extra_kwargs)[source]
get_current_phase(requested_phase_identifier)[source]
get_next_phase(current_phase)[source]
get_previous_phase(current_phase)[source]
prepare_current_phase(phase_identifier)[source]
add_phase_attributes(target_phase, current_phase=None)[source]

Add phase instance attributes (previous, next, etc) to the given target phase, using the optional current_phase as the current phase for previous and next.

This is exposed as a public API for the benefit of phases that need to do sub-phase initialization and dispatching, such as method phases.

reset()[source]
complete()[source]

To be called from a phase (self.checkout_process.complete()) when the checkout process is complete.

shoop.front.models package
Submodules
shoop.front.models.stored_basket module
shoop.front.models.stored_basket.generate_key()[source]
class shoop.front.models.stored_basket.StoredBasket(id, key, shop, customer, orderer, creator, created_on, updated_on, persistent, deleted, finished, title, data, taxless_total_price_value, taxful_total_price_value, currency, prices_include_tax, product_count)[source]

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

shop
customer
orderer
creator
data

A placeholder class that provides a way to set the attribute on the model.

taxful_total_price
taxless_total_price
products
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception StoredBasket.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

StoredBasket.get_next_by_created_on(*moreargs, **morekwargs)
StoredBasket.get_next_by_updated_on(*moreargs, **morekwargs)
StoredBasket.get_previous_by_created_on(*moreargs, **morekwargs)
StoredBasket.get_previous_by_updated_on(*moreargs, **morekwargs)
StoredBasket.objects = <django.db.models.manager.Manager object>
Module contents
class shoop.front.models.StoredBasket(id, key, shop, customer, orderer, creator, created_on, updated_on, persistent, deleted, finished, title, data, taxless_total_price_value, taxful_total_price_value, currency, prices_include_tax, product_count)[source]

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception StoredBasket.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

StoredBasket.creator
StoredBasket.customer
StoredBasket.data

A placeholder class that provides a way to set the attribute on the model.

StoredBasket.get_next_by_created_on(*moreargs, **morekwargs)
StoredBasket.get_next_by_updated_on(*moreargs, **morekwargs)
StoredBasket.get_previous_by_created_on(*moreargs, **morekwargs)
StoredBasket.get_previous_by_updated_on(*moreargs, **morekwargs)
StoredBasket.objects = <django.db.models.manager.Manager object>
StoredBasket.orderer
StoredBasket.products
StoredBasket.shop
StoredBasket.taxful_total_price
StoredBasket.taxless_total_price
shoop.front.template_helpers package
Submodules
shoop.front.template_helpers.category module
shoop.front.template_helpers.category.get_manufacturers(context)[source]
shoop.front.template_helpers.general module
shoop.front.template_helpers.general.get_best_selling_products(context, n_products=12, cutoff_days=30, no_variation_children=False)[source]
shoop.front.template_helpers.general.get_newest_products(context, n_products=6)[source]
shoop.front.template_helpers.general.get_random_products(context, n_products=6)[source]
shoop.front.template_helpers.general.get_all_manufacturers(context)[source]
shoop.front.template_helpers.general.get_root_categories(context)[source]
shoop.front.template_helpers.general.get_pagination_variables(context, objects, limit)[source]

Get pagination variables for template

Parameters:
  • context – template context
  • objects – objects paginated
  • limit – per page limit
Returns:

variables to render object-list with pagination

shoop.front.template_helpers.product module
shoop.front.template_helpers.product.get_visible_attributes(product)[source]
shoop.front.template_helpers.product.get_products_bought_with(context, product, count=5)[source]
shoop.front.template_helpers.product.is_visible(context, product)[source]
shoop.front.template_helpers.product.get_product_cross_sells(context, product, relation_type='related', count=4)[source]
shoop.front.template_helpers.urls module
shoop.front.template_helpers.urls.model_url(context, model, absolute=False)[source]
shoop.front.template_helpers.urls.get_url(url, *args, **kwargs)[source]

Try to get the reversed URL for the given route name, args and kwargs.

If reverse resolution fails, returns None (instead of throwing an exception).

Parameters:
  • url (str) – URL name.
  • args (Iterable[object]) – URL args
  • kwargs (dict[str, object]) – URL kwargs
Returns:

Reversed URL or None

Return type:

str|None

shoop.front.template_helpers.urls.has_url(url, *args, **kwargs)[source]

Try to get the reversed URL for the given route name, args and kwargs and return a success flag.

Parameters:
  • url (str) – URL name.
  • args (Iterable[object]) – URL args
  • kwargs (dict[str, object]) – URL kwargs
Returns:

Success flag

Return type:

bool

Module contents
shoop.front.templatetags package
Submodules
shoop.front.templatetags.shoop_front module
class shoop.front.templatetags.shoop_front.HelpersNamespace[source]

Bases: object

shoop.front.templatetags.shoop_front.markdown(value)[source]
shoop.front.templatetags.thumbnails module
shoop.front.templatetags.thumbnails.process_thumbnailer_options(kwargs)[source]
shoop.front.templatetags.thumbnails.thumbnail(source, alias=None, generate=True, **kwargs)[source]
shoop.front.templatetags.thumbnails.thumbnailer(source)[source]
Module contents
shoop.front.utils package
Submodules
shoop.front.utils.product_sorting module
shoop.front.utils.product_sorting.sort_products(request, products, sort)[source]
shoop.front.utils.product_statistics module
shoop.front.utils.product_statistics.get_best_selling_product_info(shop_ids, cutoff_days=30)[source]
shoop.front.utils.product_statistics.get_products_ordered_with(prod, count=20, request=None, language=None)[source]
shoop.front.utils.product_statistics.get_products_by_brand(prod, count=6, request=None, language=None)[source]
shoop.front.utils.product_statistics.get_products_by_same_categories(prod, count=6, request=None, language=None)[source]
shoop.front.utils.views module
shoop.front.utils.views.cache_product_things(request, products, language=None, attribute_identifiers=('author', ))[source]
Module contents
shoop.front.views package
Submodules
shoop.front.views.basket module
class shoop.front.views.basket.DefaultBasketView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/basket/default_basket.jinja'
get_context_data(**kwargs)[source]
class shoop.front.views.basket.BasketView(**kwargs)[source]

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

dispatch(request, *args, **kwargs)[source]
shoop.front.views.category module
class shoop.front.views.category.ProductListForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

base_fields = OrderedDict([('sort', <django.forms.fields.CharField object at 0x7f655ca53128>), ('manufacturers', <django.forms.models.ModelMultipleChoiceField object at 0x7f655ca53c88>)])
declared_fields = OrderedDict([('sort', <django.forms.fields.CharField object at 0x7f655ca53128>), ('manufacturers', <django.forms.models.ModelMultipleChoiceField object at 0x7f655ca53c88>)])
media
class shoop.front.views.category.CategoryView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/product/category.jinja'
model

alias of Category

template_object_name = 'category'
get_queryset()[source]
get_context_data(**kwargs)[source]
shoop.front.views.checkout module
class shoop.front.views.checkout.BaseCheckoutView(**kwargs)[source]

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

phase_specs = []
empty_phase_spec = None
dispatch(request, *args, **kwargs)[source]
shoop.front.views.index module
class shoop.front.views.index.IndexView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/index.jinja'
get_context_data(**kwargs)[source]
shoop.front.views.order module
class shoop.front.views.order.OrderCompleteView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/order/complete.jinja'
model

alias of Order

context_object_name = 'order'
render_to_response(context, **response_kwargs)[source]
get_object(queryset=None)[source]
class shoop.front.views.order.OrderRequiresVerificationView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/order/requires_verification.jinja'
model

alias of Order

get_object(queryset=None)[source]
get_context_data(**kwargs)[source]
get(request, **kwargs)[source]
shoop.front.views.payment module
shoop.front.views.payment.get_payment_urls(request, order)[source]
class shoop.front.views.payment.ProcessPaymentView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Order

context_object_name = 'order'
get_object(queryset=None)[source]
get_context_data(**kwargs)[source]
dispatch(request, *args, **kwargs)[source]
shoop.front.views.product module
class shoop.front.views.product.ProductDetailView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/front/product/detail.jinja'
model

alias of Product

context_object_name = 'product'
get_queryset()[source]
get_context_data(**kwargs)[source]
get(request, *args, **kwargs)[source]
Module contents
Submodules
shoop.front.admin_module module
shoop.front.admin_module.get_unfinalized_basket_block(currency, days=14)[source]
class shoop.front.admin_module.BasketAdminModule(currency=None, *args, **kwargs)[source]

Bases: shoop.admin.currencybound.CurrencyBound, shoop.admin.base.AdminModule

get_dashboard_blocks(request)[source]
shoop.front.error_handling module
shoop.front.error_handling.make_error_view(status, template_name=None)[source]
shoop.front.error_handling.install_error_handlers()[source]

Install custom error handlers.

Error handlers to be added are for errors 400, 403, 404, and 500.

Error handlers will be injected only if: * settings.SHOOP_FRONT_INSTALL_ERROR_HANDLERS is True * settings.ROOT_URLCONF doesn’t already contain the handler

shoop.front.middleware module
shoop.front.middleware.ProblemMiddleware

alias of ExceptionMiddleware

class shoop.front.middleware.ShoopFrontMiddleware[source]

Bases: object

Handle Shoop specific tasks for each request and response.

  • Set request attributes that rest of the Shoop front-end rely on.

  • Set Django’s timezone according to personal preferences (i.e. request.person.timezone).

    Todo

    Fallback to shop timezone?

  • Make sure that basket is saved before response is returned to the browser.

Attributes set for requests:

request.shop : shoop.core.models.Shop

Currently active Shop.

Todo

Define better

request.person : shoop.core.models.Contact
PersonContact of currently logged in user or AnonymousContact if there is no logged in user.
request.customer : shoop.core.models.Contact
Customer contact used when creating Orders. This can be same as request.person, but for example in B2B shops this is usually a CompanyContact whereas request.person is a PersonContact.
request.basket : shoop.front.basket.objects.BaseBasket
Shopping basket in use.
process_request(request)[source]
process_response(request, response)[source]
classmethod refresh_on_user_change(request, user=None, **kwargs)[source]
classmethod refresh_on_logout(request, **kwargs)[source]
process_view(request, view_func, *view_args, **view_kwargs)[source]
shoop.front.notify_events module
class shoop.front.notify_events.OrderReceived(**variable_values)[source]

Bases: shoop.notify.base.Event

identifier = 'order_received'
bindings = {}
name = 'Order Received'
variables = {'language': <shoop.notify.base.Variable object at 0x7f6557d1dda0>, 'customer_phone': <shoop.notify.base.Variable object at 0x7f6557d1dc50>, 'customer_email': <shoop.notify.base.Variable object at 0x7f6557d1d048>, 'order': <shoop.notify.base.Variable object at 0x7f6557d1d0f0>}
shoop.front.notify_events.send_order_received_notification(order, **kwargs)[source]
shoop.front.settings module
shoop.front.settings.SHOOP_BASKET_ORDER_CREATOR_SPEC = 'shoop.front.basket.order_creator:BasketOrderCreator'

Spec string for the class used for creating Order from a Basket.

This is the easiest way to customize the order creation process without having to override a single URL or touch the shoop.front code.

shoop.front.settings.SHOOP_BASKET_VIEW_SPEC = 'shoop.front.views.basket:DefaultBasketView'

Spec string for the Django CBV (or an API-compliant class) for the basket view.

This view deals with /basket/.

shoop.front.settings.SHOOP_BASKET_COMMAND_DISPATCHER_SPEC = 'shoop.front.basket.command_dispatcher:BasketCommandDispatcher'

Spec string for the command dispatcher used when products are added/deleted/etc. from the basket.

This view deals with commands POST``ed to ``/basket/.

shoop.front.settings.SHOOP_BASKET_UPDATE_METHODS_SPEC = 'shoop.front.basket.update_methods:BasketUpdateMethods'

Spec string for the update method dispatcher used when the basket is updated (usually on the basket page).

shoop.front.settings.SHOOP_BASKET_CLASS_SPEC = 'shoop.front.basket.objects:BaseBasket'

Spec string for the basket class used in the frontend.

This is used to customize the behavior of the basket for a given installation, for instance to modify prices of products based on certain conditions, etc.

shoop.front.settings.SHOOP_BASKET_STORAGE_CLASS_SPEC = 'shoop.front.basket.storage:DatabaseBasketStorage'

The spec string defining which basket storage class to use for the frontend.

Basket storages are responsible for persisting visitor basket state, whether in the database (DatabaseBasketStorage) or directly in the session (DirectSessionBasketStorage). Custom storage backends could use caches, flat files, etc. if required.

shoop.front.settings.SHOOP_CHECKOUT_VIEW_SPEC = 'shoop.front.views.checkout:DefaultCheckoutView'

Spec string for the Django CBV (or an API-compliant class) for the checkout view.

This is used to customize the behavior of the checkout process; most likely to switch in a view with a different phase_specs.

shoop.front.settings.SHOOP_FRONT_INSTALL_ERROR_HANDLERS = True

Whether Shoop uses its own error handlers.

If this value is set to False django defaults are used or the ones specified in settings.ROOT_URLCONF file.

Setting this to True won’t override handlers specified in settings.ROOT_URLCONF.

Handled error cases are: 400, 403, 404, and 500

shoop.front.signals module
shoop.front.urls module
Module contents
class shoop.front.ShoopFrontAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.front'
verbose_name = 'Shoop Frontend'
label = 'shoop_front'
provides = {'notify_event': ['shoop.front.notify_events:OrderReceived'], 'admin_module': ['shoop.front.admin_module.BasketAdminModule']}
ready()[source]
shoop.notify package
Subpackages
shoop.notify.actions package
Submodules
shoop.notify.actions.debug module
class shoop.notify.actions.debug.SetDebugFlag(data, validate=True)[source]

Bases: shoop.notify.base.Action

identifier = 'set_debug_flag'
execute(context)[source]
bindings = {'flag_name': <shoop.notify.base.Binding object at 0x7f655802ca58>}
name = 'Set Debug Flag'
variables = {}
shoop.notify.actions.email module
class shoop.notify.actions.email.SendEmail(data, validate=True)[source]

Bases: shoop.notify.base.Action

identifier = 'send_email'
template_use = <TemplateUse.MULTILINGUAL: 2>
template_fields = {'subject': <django.forms.fields.CharField object at 0x7f655802c780>, 'body': <django.forms.fields.CharField object at 0x7f6557512dd8>}
execute(context)[source]
Parameters:context (shoop.notify.script.Context) – Script Context
bindings = {'fallback_language': <shoop.notify.base.Binding object at 0x7f6557f113c8>, 'send_identifier': <shoop.notify.base.Binding object at 0x7f6557f11c88>, 'language': <shoop.notify.base.Binding object at 0x7f6557f11438>, 'recipient': <shoop.notify.base.Binding object at 0x7f6557d1da90>}
name = 'Send Email'
variables = {}
shoop.notify.actions.notification module
class shoop.notify.actions.notification.AddNotification(data, validate=True)[source]

Bases: shoop.notify.base.Action

identifier = 'add_notification'
execute(context)[source]
bindings = {'priority': <shoop.notify.base.Binding object at 0x7f6557f11d30>, 'message_identifier': <shoop.notify.base.Binding object at 0x7f6557f11ac8>, 'recipient_type': <shoop.notify.base.Binding object at 0x7f6557f11f60>, 'recipient': <shoop.notify.base.Binding object at 0x7f6557f11eb8>, 'message': <shoop.notify.base.TemplatedBinding object at 0x7f6557f11fd0>, 'url': <shoop.notify.base.Binding object at 0x7f6557f11c18>}
name = 'Add Notification'
variables = {}
shoop.notify.actions.order module
class shoop.notify.actions.order.AddOrderLogEntry(data, validate=True)[source]

Bases: shoop.notify.base.Action

identifier = 'add_order_log_entry'
execute(context)[source]
bindings = {'message_identifier': <shoop.notify.base.Binding object at 0x7f6557f1a748>, 'order': <shoop.notify.base.Binding object at 0x7f655801dbe0>, 'message': <shoop.notify.base.Binding object at 0x7f655801d748>}
name = 'Add Order Log Entry'
variables = {}
Module contents
class shoop.notify.actions.AddNotification(data, validate=True)[source]

Bases: shoop.notify.base.Action

bindings = {'priority': <shoop.notify.base.Binding object at 0x7f6557f11d30>, 'message_identifier': <shoop.notify.base.Binding object at 0x7f6557f11ac8>, 'recipient_type': <shoop.notify.base.Binding object at 0x7f6557f11f60>, 'recipient': <shoop.notify.base.Binding object at 0x7f6557f11eb8>, 'message': <shoop.notify.base.TemplatedBinding object at 0x7f6557f11fd0>, 'url': <shoop.notify.base.Binding object at 0x7f6557f11c18>}
execute(context)[source]
identifier = 'add_notification'
name = 'Add Notification'
variables = {}
class shoop.notify.actions.AddOrderLogEntry(data, validate=True)[source]

Bases: shoop.notify.base.Action

bindings = {'message_identifier': <shoop.notify.base.Binding object at 0x7f6557f1a748>, 'order': <shoop.notify.base.Binding object at 0x7f655801dbe0>, 'message': <shoop.notify.base.Binding object at 0x7f655801d748>}
execute(context)[source]
identifier = 'add_order_log_entry'
name = 'Add Order Log Entry'
variables = {}
class shoop.notify.actions.SendEmail(data, validate=True)[source]

Bases: shoop.notify.base.Action

bindings = {'fallback_language': <shoop.notify.base.Binding object at 0x7f6557f113c8>, 'send_identifier': <shoop.notify.base.Binding object at 0x7f6557f11c88>, 'language': <shoop.notify.base.Binding object at 0x7f6557f11438>, 'recipient': <shoop.notify.base.Binding object at 0x7f6557d1da90>}
execute(context)[source]
Parameters:context (shoop.notify.script.Context) – Script Context
identifier = 'send_email'
name = 'Send Email'
template_fields = {'subject': <django.forms.fields.CharField object at 0x7f655802c780>, 'body': <django.forms.fields.CharField object at 0x7f6557512dd8>}
template_use = <TemplateUse.MULTILINGUAL: 2>
variables = {}
class shoop.notify.actions.SetDebugFlag(data, validate=True)[source]

Bases: shoop.notify.base.Action

bindings = {'flag_name': <shoop.notify.base.Binding object at 0x7f655802ca58>}
execute(context)[source]
identifier = 'set_debug_flag'
name = 'Set Debug Flag'
variables = {}
shoop.notify.admin_module package
Subpackages
shoop.notify.admin_module.views package
Submodules
shoop.notify.admin_module.views.edit module
class shoop.notify.admin_module.views.edit.ScriptEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Script

form_class

alias of ScriptForm

template_name = 'notify/admin/edit_script.jinja'
context_object_name = 'script'
get_context_data(**kwargs)[source]
form_valid(form)[source]
shoop.notify.admin_module.views.editor module
shoop.notify.admin_module.views.editor.script_item_editor(request)[source]
class shoop.notify.admin_module.views.editor.ScriptAPI(request, script)[source]

Bases: object

Parameters:
dispatch()[source]
handle_get_data(data)[source]
handle_save_data(data)[source]
class shoop.notify.admin_module.views.editor.EditScriptContentView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'notify/admin/script_content_editor.jinja'
model

alias of Script

context_object_name = 'script'
post(request, *args, **kwargs)[source]
get_context_data(**kwargs)[source]
shoop.notify.admin_module.views.list module
class shoop.notify.admin_module.views.list.ScriptListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Script

columns = [<shoop.admin.utils.picotable.Column object at 0x7f65577ec550>, <shoop.admin.utils.picotable.Column object at 0x7f65577ecc18>, <shoop.admin.utils.picotable.Column object at 0x7f65577ecd30>]
get_object_url(instance)[source]
get_event_identifier_text(instance)[source]
get_toolbar()[source]
get_object_abstract(instance, item)[source]
Module contents
shoop.notify.admin_module.views.script_item_editor(request)[source]
class shoop.notify.admin_module.views.ScriptEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'script'
form_class

alias of ScriptForm

form_valid(form)[source]
get_context_data(**kwargs)[source]
model

alias of Script

template_name = 'notify/admin/edit_script.jinja'
class shoop.notify.admin_module.views.EditScriptContentView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

context_object_name = 'script'
get_context_data(**kwargs)[source]
model

alias of Script

post(request, *args, **kwargs)[source]
template_name = 'notify/admin/script_content_editor.jinja'
class shoop.notify.admin_module.views.ScriptListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

columns = [<shoop.admin.utils.picotable.Column object at 0x7f65577ec550>, <shoop.admin.utils.picotable.Column object at 0x7f65577ecc18>, <shoop.admin.utils.picotable.Column object at 0x7f65577ecd30>]
get_event_identifier_text(instance)[source]
get_object_abstract(instance, item)[source]
get_object_url(instance)[source]
get_toolbar()[source]
model

alias of Script

Submodules
shoop.notify.admin_module.forms module
class shoop.notify.admin_module.forms.ScriptForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

class Meta[source]

Bases: object

model

alias of Script

fields = ('event_identifier', 'name', 'enabled')
ScriptForm.base_fields = OrderedDict([('event_identifier', <django.forms.fields.ChoiceField object at 0x7f6557693748>), ('name', <django.forms.fields.CharField object at 0x7f6557693320>), ('enabled', <django.forms.fields.BooleanField object at 0x7f65576937b8>)])
ScriptForm.declared_fields = OrderedDict([('event_identifier', <django.forms.fields.ChoiceField object at 0x7f6557693748>), ('name', <django.forms.fields.CharField object at 0x7f6557693320>), ('enabled', <django.forms.fields.BooleanField object at 0x7f65576937b8>)])
ScriptForm.media
class shoop.notify.admin_module.forms.ScriptItemEditForm(*args, **kwargs)[source]

Bases: django.forms.forms.Form

populate_form()[source]
get_initial()[source]
save()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
shoop.notify.admin_module.utils module
shoop.notify.admin_module.utils.get_name_map(category_key)[source]
shoop.notify.admin_module.utils.get_enum_choices_dict(enum_class)[source]
Module contents
class shoop.notify.admin_module.NotifyAdminModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
mark_notification_read_view(request, pk)[source]
get_notifications(request)[source]
get_model_url(object, kind)[source]
shoop.notify.conditions package
Submodules
shoop.notify.conditions.simple module
class shoop.notify.conditions.simple.NonEmpty(data, validate=True)[source]

Bases: shoop.notify.base.Condition

identifier = 'non_empty'
description = <django.utils.functional.lazy.<locals>.__proxy__ object>
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
test(context)[source]
bindings = {'v': <shoop.notify.base.Binding object at 0x7f65570937f0>}
variables = {}
class shoop.notify.conditions.simple.Empty(data, validate=True)[source]

Bases: shoop.notify.base.Condition

identifier = 'empty'
description = <django.utils.functional.lazy.<locals>.__proxy__ object>
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
test(context)[source]
bindings = {'v': <shoop.notify.base.Binding object at 0x7f6557093438>}
variables = {}
class shoop.notify.conditions.simple.BaseEqual(data, validate=True)[source]

Bases: shoop.notify.base.Condition

identifier_suffix = 'equal'
test(context)[source]
bindings = {}
identifier = 'base_equal'
name = 'Base Equal'
variables = {}
class shoop.notify.conditions.simple.CaseInsensitiveStringEqual(data, validate=True)[source]

Bases: shoop.notify.base.Condition

identifier_suffix = 'equal'
test(context)[source]
bindings = {}
identifier = 'case_insensitive_string_equal'
name = 'Case Insensitive String Equal'
variables = {}
shoop.notify.conditions.simple.construct_simple(base, var_type)[source]
Module contents
class shoop.notify.conditions.BooleanEqual(data, validate=True)

Bases: shoop.notify.conditions.simple.BaseEqual

bindings = {'v1': <shoop.notify.base.Binding object at 0x7f65570edf60>, 'v2': <shoop.notify.base.Binding object at 0x7f65570ed828>}
identifier = 'boolean_equal'
name = 'Boolean Equal'
variables = {}
class shoop.notify.conditions.Empty(data, validate=True)[source]

Bases: shoop.notify.base.Condition

bindings = {'v': <shoop.notify.base.Binding object at 0x7f6557093438>}
description = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'empty'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
test(context)[source]
variables = {}
class shoop.notify.conditions.IntegerEqual(data, validate=True)

Bases: shoop.notify.conditions.simple.BaseEqual

bindings = {'v1': <shoop.notify.base.Binding object at 0x7f65570ed940>, 'v2': <shoop.notify.base.Binding object at 0x7f65570ed8d0>}
identifier = 'integer_equal'
name = 'Integer Equal'
variables = {}
class shoop.notify.conditions.LanguageEqual(data, validate=True)

Bases: shoop.notify.conditions.simple.CaseInsensitiveStringEqual

bindings = {'v1': <shoop.notify.base.Binding object at 0x7f6557093668>, 'v2': <shoop.notify.base.Binding object at 0x7f65570936a0>}
identifier = 'language_equal'
name = 'Language Equal'
variables = {}
class shoop.notify.conditions.NonEmpty(data, validate=True)[source]

Bases: shoop.notify.base.Condition

bindings = {'v': <shoop.notify.base.Binding object at 0x7f65570937f0>}
description = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'non_empty'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
test(context)[source]
variables = {}
class shoop.notify.conditions.TextEqual(data, validate=True)

Bases: shoop.notify.conditions.simple.CaseInsensitiveStringEqual

bindings = {'v1': <shoop.notify.base.Binding object at 0x7f6557093358>, 'v2': <shoop.notify.base.Binding object at 0x7f65570931d0>}
identifier = 'text_equal'
name = 'Text Equal'
variables = {}
shoop.notify.models package
Submodules
shoop.notify.models.notification module
class shoop.notify.models.notification.NotificationManager[source]

Bases: django.db.models.manager.Manager

for_user(user)[source]
unread_for_user(user)[source]
class shoop.notify.models.notification.Notification(*args, **kwargs)[source]

Bases: django.db.models.base.Model

A model for persistent notifications to be shown in the admin, etc.

recipient_type

A placeholder class that provides a way to set the attribute on the model.

recipient
priority

A placeholder class that provides a way to set the attribute on the model.

marked_read_by
objects = <shoop.notify.models.notification.NotificationManager object>
save(*args, **kwargs)[source]
mark_read(user)[source]
is_read
data
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Notification.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Notification.get_next_by_created_on(*moreargs, **morekwargs)
Notification.get_previous_by_created_on(*moreargs, **morekwargs)
Notification.get_priority_display(*moreargs, **morekwargs)
Notification.get_recipient_type_display(*moreargs, **morekwargs)
Notification.url
Notification.set_reverse_url(**reverse_kwargs)[source]
shoop.notify.models.script module
class shoop.notify.models.script.Script(id, event_identifier, identifier, created_on, name, enabled, _step_data)[source]

Bases: django.db.models.base.Model

get_steps()[source]

:rtype Iterable[Step]

set_steps(steps)[source]
get_serialized_steps()[source]
set_serialized_steps(serialized_data)[source]
event_class
execute(context)[source]

Execute the script in the given context.

Parameters:context (shoop.notify.script.Context) – Script context
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Script.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Script.get_next_by_created_on(*moreargs, **morekwargs)
Script.get_previous_by_created_on(*moreargs, **morekwargs)
Script.objects = <django.db.models.manager.Manager object>
Module contents
class shoop.notify.models.Notification(*args, **kwargs)[source]

Bases: django.db.models.base.Model

A model for persistent notifications to be shown in the admin, etc.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Notification.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Notification.data
Notification.get_next_by_created_on(*moreargs, **morekwargs)
Notification.get_previous_by_created_on(*moreargs, **morekwargs)
Notification.get_priority_display(*moreargs, **morekwargs)
Notification.get_recipient_type_display(*moreargs, **morekwargs)
Notification.is_read
Notification.mark_read(user)[source]
Notification.marked_read_by
Notification.objects = <shoop.notify.models.notification.NotificationManager object>
Notification.priority

A placeholder class that provides a way to set the attribute on the model.

Notification.recipient
Notification.recipient_type

A placeholder class that provides a way to set the attribute on the model.

Notification.save(*args, **kwargs)[source]
Notification.set_reverse_url(**reverse_kwargs)[source]
Notification.url
class shoop.notify.models.Script(id, event_identifier, identifier, created_on, name, enabled, _step_data)[source]

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Script.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Script.event_class
Script.execute(context)[source]

Execute the script in the given context.

Parameters:context (shoop.notify.script.Context) – Script context
Script.get_next_by_created_on(*moreargs, **morekwargs)
Script.get_previous_by_created_on(*moreargs, **morekwargs)
Script.get_serialized_steps()[source]
Script.get_steps()[source]

:rtype Iterable[Step]

Script.objects = <django.db.models.manager.Manager object>
Script.set_serialized_steps(serialized_data)[source]
Script.set_steps(steps)[source]
Submodules
shoop.notify.base module
class shoop.notify.base.BaseMetaclass[source]

Bases: type

class shoop.notify.base.Variable(name, type=<class 'shoop.notify.typology.Type'>, required=True, help_text='')[source]

Bases: object

get_matching_types(variable_dict)[source]
class shoop.notify.base.Binding(name, type=<class 'shoop.notify.typology.Type'>, required=False, help_text='', constant_use=<ConstantUse.VARIABLE_ONLY: 1>, default=None)[source]

Bases: shoop.notify.base.Variable

accepts_any_type
allow_constant
allow_variable
get_value(context, bind_data)[source]
class shoop.notify.base.TemplatedBinding(*args, **kwargs)[source]

Bases: shoop.notify.base.Binding

get_value(context, bind_data)[source]
class shoop.notify.base.Base[source]

Bases: object

identifier = None
name = None
description = None
variables = {}
bindings = {}
provide_category = None
classmethod class_for_identifier(identifier)[source]
class shoop.notify.base.Event(**variable_values)[source]

Bases: shoop.notify.base.Base

provide_category = 'notify_event'
identifier = None
log_target_variable = None

The name of the variable to be used as the log target for this event.

The target variable must have an add_log_entry method.

log_target
load_variables(variable_values)[source]
run()[source]
bindings = {}
variables = {}
class shoop.notify.base.ScriptItem(data, validate=True)[source]

Bases: shoop.notify.base.Base

provide_category = None
verify_bindings()[source]
get_value(context, binding_name)[source]

Get the actual value of a binding from the given script context.

Parameters:
Returns:

The variable value

get_values(context)[source]

Get all binding values in a dict.

Parameters:context (shoop.notify.script.Context) – Script Context
Returns:Dict of binding name -> value
Return type:dict[name, value]
classmethod unserialize(data, validate=True)[source]
serialize()[source]
classmethod get_ui_info_map()[source]
bindings = {}
identifier = 'script_item'
name = 'Script Item'
variables = {}
class shoop.notify.base.Condition(data, validate=True)[source]

Bases: shoop.notify.base.ScriptItem

provide_category = 'notify_condition'
test(context)[source]
bindings = {}
identifier = 'condition'
name = 'Condition'
variables = {}
class shoop.notify.base.Action(data, validate=True)[source]

Bases: shoop.notify.base.ScriptItem

provide_category = 'notify_action'
template_use = <TemplateUse.NONE: 0>
template_fields = {}
execute(context)[source]
Parameters:context (shoop.notify.script.Context) – Script Context
get_template(context)[source]

Get this action’s template instance, bound in the context.

Return type:shoop.notify.template.Template
bindings = {}
get_template_values(context, language_preferences=())[source]

Render this Action’s template with data from the given context.

Parameters:
  • context (shoop.notify.script.Context) – Script Context
  • language_preferences (list[str]) – Language preference list. The first language in the template to have values for all fields will be used. Has no effect for UNILINGUAL template_use.
Returns:

Dict of field name -> rendered template text.

Return type:

dict[str, str]|None

identifier = 'action'
name = 'Action'
variables = {}
shoop.notify.enums module
class shoop.notify.enums.TemplateUse[source]

Bases: enumfields.enums.Enum

class shoop.notify.enums.ConstantUse[source]

Bases: enumfields.enums.Enum

class shoop.notify.enums.StepNext[source]

Bases: enumfields.enums.Enum

class shoop.notify.enums.StepConditionOperator[source]

Bases: enumfields.enums.Enum

class shoop.notify.enums.RecipientType[source]

Bases: enumfields.enums.Enum

class shoop.notify.enums.Priority[source]

Bases: enumfields.enums.Enum

shoop.notify.runner module
shoop.notify.runner.run_event(event)[source]
shoop.notify.script module
shoop.notify.script.none(conditions)[source]
class shoop.notify.script.Step(conditions=(), actions=(), next=<StepNext.CONTINUE: 'continue'>, cond_op=<StepConditionOperator.ALL: 'all'>, enabled=True)[source]

Bases: object

execute(context)[source]
serialize()[source]
classmethod unserialize(step_data)[source]
enabled
class shoop.notify.script.Context(variables=None)[source]

Bases: object

classmethod from_variables(**variables)[source]

Create Context from variables.

Return type:shoop.notify.script.Context
classmethod from_event(event)[source]

Create Context from event.

Return type:shoop.notify.script.Context
get(name, default=None)[source]
set(name, value)[source]
get_variables()[source]
log(level, msg, *args, **kwargs)[source]

Log a message with the context’s logger (not the log target). This may be an useful debugging tool.

The parameters are the same as for logging.Logger.log().

add_log_entry_on_log_target(message, identifier, **kwargs)[source]

Add a log entry on the context’s log target.

The kwargs are passed to the target’s add_log_entry method.

If no log target exists or if it has no add_log_entry method, this method does nothing.

Parameters:
  • message (str) – The message text.
  • identifier (str) – The message identifier. Unlike with add_log_entry, this is required.
  • kwargs (dict) – Other kwargs to pass to add_log_entry
log_entry_queryset
shoop.notify.settings module
shoop.notify.template module
exception shoop.notify.template.NoLanguageMatches[source]

Bases: Exception

shoop.notify.template.render_in_context(context, template_text, html_intent=False)[source]

Render the given Jinja2 template text in the script context.

Parameters:
  • context (shoop.notify.script.Context) – Script context.
  • template_text (str) – Jinja2 template text.
  • html_intent (bool) – Is the template text intended for HTML output? This currently turns on autoescaping.
Returns:

Rendered template text

Return type:

str

Raises:

Whatever Jinja2 might happen to raise

class shoop.notify.template.Template(context, data)[source]

Bases: object

Parameters:
has_language(language, fields)[source]
render(language, fields)[source]

Render this template in the given language, returning the given fields.

Parameters:
  • language (str) – Language code (ISO 639-1 or ISO 639-2)
  • fields (list[str]) – Desired fields to render.
Returns:

Dict of field -> rendered content.

Return type:

dict[str, str]

render_first_match(language_preferences, fields)[source]
shoop.notify.typology module
class shoop.notify.typology.Type[source]

Bases: object

name = None
identifier = None
get_field(**kwargs)[source]

Get a Django form field for this type.

The kwargs are passed directly to the field constructor.

Parameters:kwargs (dict) – Kwargs for field constructor
Returns:Form field
Return type:django.forms.Field
unserialize(value)[source]
validate(value)[source]
is_coercible_from(other_type)[source]
class shoop.notify.typology.Boolean[source]

Bases: shoop.notify.typology.Type

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'boolean'
class shoop.notify.typology.Integer[source]

Bases: shoop.notify.typology._Number

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'integer'
get_field(**kwargs)[source]
class shoop.notify.typology.Decimal[source]

Bases: shoop.notify.typology._Number

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'decimal'
get_field(**kwargs)[source]
class shoop.notify.typology.Text[source]

Bases: shoop.notify.typology._String

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'text'
is_coercible_from(other_type)[source]
class shoop.notify.typology.Language[source]

Bases: shoop.notify.typology._String

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'language'
class shoop.notify.typology.Email[source]

Bases: shoop.notify.typology._String

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'email'
get_field(**kwargs)[source]
class shoop.notify.typology.URL[source]

Bases: shoop.notify.typology._String

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'url'
get_field(**kwargs)[source]
class shoop.notify.typology.Phone[source]

Bases: shoop.notify.typology._String

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
identifier = 'phone'
class shoop.notify.typology.Model(model_label)[source]

Bases: shoop.notify.typology.Type

Parameters:model_label (str) – Model label in Django app.Model format (e.g. shoop.Order)
identifier = 'model'
name
model_label = None
unserialize(value)[source]
is_coercible_from(other_type)[source]
get_model()[source]
Return type:django.db.models.Model
get_field(**kwargs)[source]
class shoop.notify.typology.Enum(enum_class)[source]

Bases: shoop.notify.typology.Type

identifier = 'enum'
name
enum_class = None
unserialize(value)[source]
get_field(**kwargs)[source]
Module contents
class shoop.notify.Action(data, validate=True)[source]

Bases: shoop.notify.base.ScriptItem

bindings = {}
execute(context)[source]
Parameters:context (shoop.notify.script.Context) – Script Context
get_template(context)[source]

Get this action’s template instance, bound in the context.

Return type:shoop.notify.template.Template
get_template_values(context, language_preferences=())[source]

Render this Action’s template with data from the given context.

Parameters:
  • context (shoop.notify.script.Context) – Script Context
  • language_preferences (list[str]) – Language preference list. The first language in the template to have values for all fields will be used. Has no effect for UNILINGUAL template_use.
Returns:

Dict of field name -> rendered template text.

Return type:

dict[str, str]|None

identifier = 'action'
name = 'Action'
provide_category = 'notify_action'
template_fields = {}
template_use = <TemplateUse.NONE: 0>
variables = {}
class shoop.notify.Binding(name, type=<class 'shoop.notify.typology.Type'>, required=False, help_text='', constant_use=<ConstantUse.VARIABLE_ONLY: 1>, default=None)[source]

Bases: shoop.notify.base.Variable

accepts_any_type
allow_constant
allow_variable
get_value(context, bind_data)[source]
class shoop.notify.Context(variables=None)[source]

Bases: object

add_log_entry_on_log_target(message, identifier, **kwargs)[source]

Add a log entry on the context’s log target.

The kwargs are passed to the target’s add_log_entry method.

If no log target exists or if it has no add_log_entry method, this method does nothing.

Parameters:
  • message (str) – The message text.
  • identifier (str) – The message identifier. Unlike with add_log_entry, this is required.
  • kwargs (dict) – Other kwargs to pass to add_log_entry
classmethod from_event(event)[source]

Create Context from event.

Return type:shoop.notify.script.Context
classmethod from_variables(**variables)[source]

Create Context from variables.

Return type:shoop.notify.script.Context
get(name, default=None)[source]
get_variables()[source]
log(level, msg, *args, **kwargs)[source]

Log a message with the context’s logger (not the log target). This may be an useful debugging tool.

The parameters are the same as for logging.Logger.log().

log_entry_queryset
set(name, value)[source]
class shoop.notify.Condition(data, validate=True)[source]

Bases: shoop.notify.base.ScriptItem

bindings = {}
identifier = 'condition'
name = 'Condition'
provide_category = 'notify_condition'
test(context)[source]
variables = {}
class shoop.notify.ConstantUse[source]

Bases: enumfields.enums.Enum

class shoop.notify.Event(**variable_values)[source]

Bases: shoop.notify.base.Base

bindings = {}
identifier = None
load_variables(variable_values)[source]
log_target
log_target_variable = None
provide_category = 'notify_event'
run()[source]
variables = {}
class shoop.notify.TemplateUse[source]

Bases: enumfields.enums.Enum

class shoop.notify.Variable(name, type=<class 'shoop.notify.typology.Type'>, required=True, help_text='')[source]

Bases: object

get_matching_types(variable_dict)[source]
shoop.simple_cms package
Subpackages
shoop.simple_cms.admin_module package
Submodules
shoop.simple_cms.admin_module.views module
class shoop.simple_cms.admin_module.views.PageForm(**kwargs)[source]

Bases: shoop.utils.multilanguage_model_form.MultiLanguageModelForm

class Meta[source]

Bases: object

model

alias of Page

fields = ['title', 'url', 'content', 'available_from', 'available_to', 'identifier', 'visible_in_menu']
PageForm.clean()[source]

If title or content has been given on any language we must enforce that the other fields are also required in that language.

This is done the way it is because url is not required by default in model level.

PageForm.is_url_valid(language_code, field_name, url)[source]

Ensure URL given is unique.

Check through the pages translation model objects to make sure that the url given doesn’t already exist.

Possible failure cases: for new page: * URL already exists

for existing page: * URL (other than owned by existing page) exists * URL exists in other languages of existing page

PageForm.base_fields = OrderedDict([('title', <django.forms.fields.CharField object at 0x7f6557028a90>), ('url', <django.forms.fields.CharField object at 0x7f65579cab38>), ('content', <django.forms.fields.CharField object at 0x7f65579ca518>), ('available_from', <django.forms.fields.DateTimeField object at 0x7f65578547b8>), ('available_to', <django.forms.fields.DateTimeField object at 0x7f65570286a0>), ('identifier', <django.forms.fields.CharField object at 0x7f65579ca9e8>), ('visible_in_menu', <django.forms.fields.BooleanField object at 0x7f65577ff160>)])
PageForm.declared_fields = OrderedDict([('available_from', <django.forms.fields.DateTimeField object at 0x7f65578547b8>), ('available_to', <django.forms.fields.DateTimeField object at 0x7f65570286a0>), ('title', <django.forms.fields.CharField object at 0x7f6557028a90>), ('url', <django.forms.fields.CharField object at 0x7f65579cab38>), ('content', <django.forms.fields.CharField object at 0x7f65579ca518>)])
PageForm.media
class shoop.simple_cms.admin_module.views.PageEditView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Page

template_name = 'shoop/simple_cms/admin/edit.jinja'
form_class

alias of PageForm

context_object_name = 'page'
add_form_errors_as_messages = True
save_form(form)[source]
class shoop.simple_cms.admin_module.views.PageListView(**kwargs)[source]

Bases: shoop.admin.utils.views.PicotableListView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Page

columns = [<shoop.admin.utils.picotable.Column object at 0x7f65579caa90>, <shoop.admin.utils.picotable.Column object at 0x7f65579ca8d0>, <shoop.admin.utils.picotable.Column object at 0x7f65579ca240>, <shoop.admin.utils.picotable.Column object at 0x7f65577ff208>, <shoop.admin.utils.picotable.Column object at 0x7f65577ffef0>]
get_object_abstract(instance, item)[source]
Module contents
class shoop.simple_cms.admin_module.SimpleCMSAdminModule[source]

Bases: shoop.admin.base.AdminModule

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_model_url(object, kind)[source]
Submodules
shoop.simple_cms.models module
class shoop.simple_cms.models.PageQuerySet(*args, **kwargs)[source]

Bases: parler.managers.TranslatableQuerySet

visible(dt=None)[source]

Get pages that should be publicly visible.

This does not do permission checking.

Parameters:dt (datetime.datetime) – Datetime for visibility check
Returns:QuerySet of pages.
Return type:QuerySet[Page]
class shoop.simple_cms.models.Page(id, available_from, available_to, created_by, modified_by, created_on, modified_on, identifier, visible_in_menu)[source]

Bases: parler.models.TranslatableModel

created_by
modified_by
translations
objects = <django.db.models.manager.ManagerFromPageQuerySet object>
is_visible(dt=None)[source]
get_html()[source]
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Page.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Page.content

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Page.get_next_by_created_on(*moreargs, **morekwargs)
Page.get_next_by_modified_on(*moreargs, **morekwargs)
Page.get_previous_by_created_on(*moreargs, **morekwargs)
Page.get_previous_by_modified_on(*moreargs, **morekwargs)
Page.title

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

Page.url

Descriptor for translated attributes.

This attribute proxies all get/set calls to the translated model.

class shoop.simple_cms.models.PageTranslation(id, language_code, title, url, content, master)

Bases: parler.models.TranslatedFieldsModel

exception DoesNotExist

Bases: parler.models.TranslationDoesNotExist, shoop.simple_cms.models.DoesNotExist, shoop.simple_cms.models.DoesNotExist

exception PageTranslation.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

PageTranslation.get_language_code_display(*moreargs, **morekwargs)
PageTranslation.master
PageTranslation.objects = <django.db.models.manager.Manager object>
shoop.simple_cms.template_helpers module
class shoop.simple_cms.template_helpers.SimpleCMSTemplateHelpers[source]

Bases: object

name = 'simple_cms'
get_page_by_identifier(identifier)[source]
get_visible_pages()[source]
shoop.simple_cms.urls module
shoop.simple_cms.views module
class shoop.simple_cms.views.PageView(**kwargs)[source]

Bases: django.views.generic.detail.DetailView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of Page

slug_field = 'translations__url'
slug_url_kwarg = 'url'
template_name = 'shoop/simple_cms/page.jinja'
context_object_name = 'page'
get(request, *args, **kwargs)[source]

Override normal get method to return correct page based on the active language and slug

Cases:
  1. Page is not found: raise Http404() like django would

  2. No translation in active language for the page: raise Http404()

  3. Translation was found for active language, but the url doesn’t match given url:

    return HttpResponseRedirect to the active languages url

  4. If none of the upper matches: render page normally

get_queryset()[source]
Module contents
class shoop.simple_cms.AppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.simple_cms'
verbose_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
label = 'shoop_simple_cms'
provides = {'front_urls_post': ['shoop.simple_cms.urls:urlpatterns'], 'admin_module': ['shoop.simple_cms.admin_module:SimpleCMSAdminModule'], 'front_template_helper_namespace': ['shoop.simple_cms.template_helpers:SimpleCMSTemplateHelpers']}
shoop.simple_pricing package
Submodules
shoop.simple_pricing.admin_form_part module
class shoop.simple_pricing.admin_form_part.SimplePricingForm(**kwargs)[source]

Bases: django.forms.forms.Form

save()[source]
get_shop_group_field(shop, group)[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.simple_pricing.admin_form_part.SimplePricingFormPart(request, object=None)[source]

Bases: shoop.admin.form_part.FormPart

priority = 10
get_form_defs()[source]
form_valid(form)[source]
shoop.simple_pricing.api module
shoop.simple_pricing.api.populate_simple_pricing_api(router)[source]
Parameters:router (rest_framework.routers.DefaultRouter) – Router
shoop.simple_pricing.models module
class shoop.simple_pricing.models.SimpleProductPrice(id, product, shop, group, price_value)[source]

Bases: shoop.utils.properties.MoneyPropped, django.db.models.base.Model

product
shop
group
price

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception SimpleProductPrice.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

SimpleProductPrice.objects = <django.db.models.manager.Manager object>
shoop.simple_pricing.module module
class shoop.simple_pricing.module.SimplePricingContext(**kwargs)[source]

Bases: shoop.core.pricing.PricingContext

REQUIRED_VALUES = ('customer_group_ids', 'shop')
customer_group_ids = ()
shop = None
class shoop.simple_pricing.module.SimplePricingModule[source]

Bases: shoop.core.pricing.PricingModule

identifier = 'simple_pricing'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
pricing_context_class

alias of SimplePricingContext

get_context_from_request(request)[source]
get_price_info(context, product, quantity=1)[source]
Module contents
class shoop.simple_pricing.ShoopSimplePricingAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.simple_pricing'
verbose_name = 'Shoop Simple Pricing'
label = 'simple_pricing'
provides = {'pricing_module': ['shoop.simple_pricing.module:SimplePricingModule'], 'api_populator': ['shoop.simple_pricing.api:populate_simple_pricing_api'], 'admin_product_form_part': ['shoop.simple_pricing.admin_form_part:SimplePricingFormPart']}
shoop.simple_supplier package
Submodules
shoop.simple_supplier.models module
class shoop.simple_supplier.models.StockAdjustment(id, product, supplier, created_on, created_by, delta)[source]

Bases: django.db.models.base.Model

product
supplier
created_by
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception StockAdjustment.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

StockAdjustment.get_next_by_created_on(*moreargs, **morekwargs)
StockAdjustment.get_previous_by_created_on(*moreargs, **morekwargs)
StockAdjustment.objects = <django.db.models.manager.Manager object>
class shoop.simple_supplier.models.StockCount(id, product, supplier, logical_count, physical_count)[source]

Bases: django.db.models.base.Model

product
supplier
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception StockCount.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

StockCount.objects = <django.db.models.manager.Manager object>
shoop.simple_supplier.module module
class shoop.simple_supplier.module.SimpleSupplierModule(supplier, options)[source]

Bases: shoop.core.suppliers.base.BaseSupplierModule

identifier = 'simple_supplier'
name = 'Simple Supplier'
get_stock_statuses(product_ids)[source]
adjust_stock(product_id, delta, created_by=None)[source]
update_stock(product_id)[source]
shoop.simple_supplier.utils module
shoop.simple_supplier.utils.get_current_stock_value(supplier_id, product_id)[source]
Module contents
class shoop.simple_supplier.ShoopSimpleSupplierAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.simple_supplier'
verbose_name = 'Shoop Simple Supplier'
label = 'simple_supplier'
provides = {'supplier_module': ['shoop.simple_supplier.module:SimpleSupplierModule']}
shoop.testing package
Subpackages
shoop.testing.admin_module package
Submodules
shoop.testing.admin_module.mocker_view module
class shoop.testing.admin_module.mocker_view.Mockers[source]

Bases: object

Namespace object for mocker methods.

The docstrings for the callables are user-visible.

mock_order()[source]

Create a random order

mock_person()[source]

Create a random person

mock_company()[source]

Create a random company

class shoop.testing.admin_module.mocker_view.MockerForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

base_fields = OrderedDict([('type', <django.forms.fields.ChoiceField object at 0x7f6556f9e668>), ('count', <django.forms.fields.IntegerField object at 0x7f6556f9e860>)])
declared_fields = OrderedDict([('type', <django.forms.fields.ChoiceField object at 0x7f6556f9e668>), ('count', <django.forms.fields.IntegerField object at 0x7f6556f9e860>)])
media
class shoop.testing.admin_module.mocker_view.MockerView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

form_class

alias of MockerForm

template_name = 'shoop_testing/mocker.jinja'
mockers = <shoop.testing.admin_module.mocker_view.Mockers object>
get_mockers()[source]
get_form(form_class=None)
form_valid(form)[source]
Module contents
class shoop.testing.admin_module.TestingAdminModule[source]

Bases: shoop.admin.base.AdminModule

get_urls()[source]
get_menu_entries(request)[source]
shoop.testing.management package
Subpackages
shoop.testing.management.commands package
Submodules
shoop.testing.management.commands.shoop_populate_mock module
class shoop.testing.management.commands.shoop_populate_mock.Command(stdout=None, stderr=None, no_color=False)[source]

Bases: django.core.management.base.BaseCommand

option_list = (<Option at 0x7f6556c36080: --with-superuser>,)
handle(*args, **options)[source]
Module contents
Module contents
Submodules
shoop.testing.factories module
class shoop.testing.factories.FuzzyBoolean(probability, **kwargs)[source]

Bases: factory.fuzzy.BaseFuzzyAttribute

fuzz()[source]
class shoop.testing.factories.UserFactory[source]

Bases: factory.django.DjangoModelFactory

username = <factory.declarations.Sequence object>
email = <factory.declarations.Sequence object>
password = <factory.declarations.PostGenerationMethodCall object>
first_name = <factory.fuzzy.FuzzyText object>
last_name = <factory.fuzzy.FuzzyText object>
class shoop.testing.factories.CompanyFactory[source]

Bases: factory.django.DjangoModelFactory

name = <factory.fuzzy.FuzzyText object>
vat_id = <factory.fuzzy.FuzzyText object>
email = <factory.declarations.Sequence object>
class shoop.testing.factories.ShopFactory[source]

Bases: factory.django.DjangoModelFactory

slug = <factory.fuzzy.FuzzyText object>
name = <factory.fuzzy.FuzzyText object>
owner = <factory.declarations.SubFactory object>
class shoop.testing.factories.ProductTypeFactory[source]

Bases: factory.django.DjangoModelFactory

identifier = <factory.declarations.Sequence object>
name = <factory.fuzzy.FuzzyText object>
class shoop.testing.factories.SalesUnitFactory[source]

Bases: factory.django.DjangoModelFactory

name = <factory.fuzzy.FuzzyText object>
short_name = <factory.fuzzy.FuzzyText object>
class shoop.testing.factories.CategoryFactory[source]

Bases: factory.django.DjangoModelFactory

identifier = <factory.declarations.Sequence object>
name = <factory.fuzzy.FuzzyText object>
status = <factory.fuzzy.FuzzyChoice object>
post = <factory.declarations.PostGeneration object>
class shoop.testing.factories.ShopProductFactory[source]

Bases: factory.django.DjangoModelFactory

visible = <shoop.testing.factories.FuzzyBoolean object>
listed = <shoop.testing.factories.FuzzyBoolean object>
purchasable = <shoop.testing.factories.FuzzyBoolean object>
searchable = <shoop.testing.factories.FuzzyBoolean object>
default_price_value = <factory.fuzzy.FuzzyDecimal object>
class shoop.testing.factories.FuzzyName(prefix='', length=12, suffix='', chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', **kwargs)[source]

Bases: factory.fuzzy.FuzzyText

fuzz()[source]
class shoop.testing.factories.ProductFactory[source]

Bases: factory.django.DjangoModelFactory

type = <factory.declarations.LazyAttribute object>
sku = <factory.fuzzy.FuzzyText object>
sales_unit = <factory.declarations.LazyAttribute object>
tax_class = <factory.declarations.LazyAttribute object>
profit_center = <factory.fuzzy.FuzzyInteger object>
cost_center = <factory.fuzzy.FuzzyInteger object>
name = <shoop.testing.factories.FuzzyName object>
post = <factory.declarations.PostGeneration object>
shoop.testing.factories.get_address(**overrides)[source]
shoop.testing.factories.default_by_identifier(model)[source]
shoop.testing.factories.get_default_attribute_set()[source]
shoop.testing.factories.get_default_product_type()[source]
shoop.testing.factories.get_tax(code, name, rate=None, amount=None)[source]
shoop.testing.factories.create_default_tax_rule(tax)[source]
shoop.testing.factories.get_default_tax()[source]
shoop.testing.factories.get_test_tax(rate)[source]
shoop.testing.factories.get_default_tax_class()[source]
shoop.testing.factories.get_default_payment_method()[source]
shoop.testing.factories.get_default_shipping_method()[source]
shoop.testing.factories.get_default_customer_group()[source]
shoop.testing.factories.get_default_supplier()[source]
shoop.testing.factories.get_default_shop()[source]
shoop.testing.factories.get_shop(prices_include_tax, currency='EUR')[source]
shoop.testing.factories.get_default_product()[source]
shoop.testing.factories.get_default_shop_product()[source]
shoop.testing.factories.get_default_sales_unit()[source]
shoop.testing.factories.get_default_category()[source]
shoop.testing.factories.get_initial_order_status()[source]
shoop.testing.factories.get_completed_order_status()[source]
shoop.testing.factories.create_product(sku, shop=None, supplier=None, default_price=None)[source]
shoop.testing.factories.create_empty_order(prices_include_tax=False, shop=None)[source]
shoop.testing.factories.create_order_with_product(product, supplier, quantity, taxless_base_unit_price, tax_rate=0, n_lines=1, shop=None)[source]
shoop.testing.factories.get_random_filer_image()[source]
shoop.testing.factories.get_faker(providers, locale=None)[source]
shoop.testing.factories.create_random_address(fake=None, **values)[source]
shoop.testing.factories.create_random_person(locale=None, minimum_name_comp_len=0)[source]

Create a random PersonContact from the given locale (or a random one).

The minimum length for name components can be given, to work around possible issues with components expecting a long-enough string.

Parameters:
  • locale (str|None) – Locale name
  • minimum_name_comp_len (int) – Minimum name component length
Returns:

Person contact

Return type:

PersonContact

shoop.testing.factories.create_random_company()[source]
shoop.testing.factories.create_random_order(customer=None, products=(), completion_probability=0, shop=None)[source]
shoop.testing.image_generator module
class shoop.testing.image_generator.BaseImageGenerator(image, palette, seed)[source]

Bases: object

Parameters:
  • image (PIL.Image.Image) – The image to draw on
  • palette – A list of RGB tuples
  • seed (int) – Random generator seed
generate()[source]
draw_circle(x, y, w, h, color)[source]
draw_rectangle(x, y, w, h, color)[source]
class shoop.testing.image_generator.RandomImageGenerator(image, palette, seed)[source]

Bases: shoop.testing.image_generator.BaseImageGenerator

Parameters:
  • image (PIL.Image.Image) – The image to draw on
  • palette – A list of RGB tuples
  • seed (int) – Random generator seed
generate()[source]
step()[source]
class shoop.testing.image_generator.ModernArtImageGenerator(image, palette, seed)[source]

Bases: shoop.testing.image_generator.BaseImageGenerator

Parameters:
  • image (PIL.Image.Image) – The image to draw on
  • palette – A list of RGB tuples
  • seed (int) – Random generator seed
generate()[source]
class shoop.testing.image_generator.RingImageGenerator(image, palette, seed)[source]

Bases: shoop.testing.image_generator.BaseImageGenerator

Parameters:
  • image (PIL.Image.Image) – The image to draw on
  • palette – A list of RGB tuples
  • seed (int) – Random generator seed
generate()[source]
shoop.testing.image_generator.generate_image(width, height, palette=None, seed=None, supersample=2)[source]
shoop.testing.mock_population module
class shoop.testing.mock_population.Populator[source]

Bases: object

populate()[source]
generate_pricing(product)[source]
populate_if_required()[source]
shoop.testing.mock_population.populate_if_required()[source]
shoop.testing.pseudo_payment module
class shoop.testing.pseudo_payment.ExampleDetailViewClass(**kwargs)[source]

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

dispatch(request, *args, **kwargs)[source]
class shoop.testing.pseudo_payment.PseudoPaymentMethodModule(method, options)[source]

Bases: shoop.core.methods.base.BasePaymentMethodModule

identifier = 'pseudo_payment'
name = 'Shoop Pseudo Payment'
admin_detail_view_class

alias of ExampleDetailViewClass

option_fields = [('price', <django.forms.fields.DecimalField object at 0x7f65593e3ac8>), ('price_waiver_product_minimum', <django.forms.fields.DecimalField object at 0x7f65593e39b0>), ('bg_color', <django.forms.fields.CharField object at 0x7f6556b4f208>), ('fg_color', <django.forms.fields.CharField object at 0x7f6556b5d470>)]
compute_pseudo_mac(order)[source]
get_payment_process_response(order, urls)[source]
process_payment_return_request(order, request)[source]
shoop.testing.soup_utils module
shoop.testing.soup_utils.extract_form_fields(soup)[source]

Turn a BeautifulSoup form in to a dict of fields and default values

shoop.testing.text_data module
shoop.testing.text_data.random_title(second_adj_chance=0.3, prefix='', suffix='')[source]
shoop.testing.utils module
shoop.testing.utils.apply_request_middleware(request, **attrs)[source]

Apply all the process_request capable middleware configured into the given request.

Parameters:
Returns:

The same request, massaged in-place.

Return type:

django.http.HttpRequest

Module contents
class shoop.testing.ShoopTestingAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.testing'
verbose_name = 'Shoop Testing & Demo Utilities'
label = 'shoop_testing'
provides = {'admin_module': ['shoop.testing.admin_module:TestingAdminModule'], 'payment_method_module': ['shoop.testing.pseudo_payment:PseudoPaymentMethodModule']}
shoop.themes package
Subpackages
shoop.themes.classic_gray package
Subpackages
shoop.themes.classic_gray.views package
Module contents
shoop.themes.classic_gray.views.basket_partial(request)
shoop.themes.classic_gray.views.product_preview(request)
shoop.themes.classic_gray.views.products(request)
shoop.themes.classic_gray.views.product_price(request)
Submodules
shoop.themes.classic_gray.config_form module
class shoop.themes.classic_gray.config_form.ClassicGrayConfigForm(**kwargs)[source]

Bases: shoop.xtheme.forms.GenericThemeForm

clean()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
shoop.themes.classic_gray.plugins module
class shoop.themes.classic_gray.plugins.ProductHighlightPlugin(config)[source]

Bases: shoop.xtheme.TemplatedPlugin

Instantiate a Plugin with the given config dictionary.

Parameters:config (dict) – Dictionary of freeform configuration data
identifier = 'classic_gray.product_highlight'
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
template_name = 'classic_gray/highlight_plugin.jinja'
fields = [('title', <shoop.xtheme.plugins.forms.TranslatableField object at 0x7f6556dc22e8>), ('type', <django.forms.fields.ChoiceField object at 0x7f6556dc2390>), ('count', <django.forms.fields.IntegerField object at 0x7f6556dc2438>)]
get_context_data(context)[source]
Module contents
class shoop.themes.classic_gray.ClassicGrayTheme(settings_obj=None)[source]

Bases: shoop.xtheme.Theme

Initialize this theme, with an optional ThemeSettings object

Parameters:settings_obj (ThemeSettings|None) – A theme settings object for this theme, if one exists. Passing this in will avoid extraneous database queries.
identifier = 'shoop.themes.classic_gray'
name = 'Shoop Classic Gray Theme'
author = 'Juha Kujala'
template_dir = 'classic_gray/'
fields = [('show_welcome_text', <django.forms.fields.BooleanField object at 0x7f655ec255f8>), ('footer_html', <django.forms.fields.CharField object at 0x7f655ec25668>), ('footer_links', <django.forms.fields.CharField object at 0x7f655ebb1908>), ('footer_column_order', <django.forms.fields.ChoiceField object at 0x7f655eb69860>)]
get_configuration_form(form_kwargs)[source]
get_view(view_name)[source]
class shoop.themes.classic_gray.ClassicGrayThemeAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.themes.classic_gray'
verbose_name = 'Shoop Classic Gray Theme'
label = 'shoop.themes.classic_gray'
provides = {'xtheme': 'shoop.themes.classic_gray:ClassicGrayTheme', 'xtheme_plugin': ['shoop.themes.classic_gray.plugins:ProductHighlightPlugin']}
Module contents
shoop.utils package
Submodules
shoop.utils.analog module
class shoop.utils.analog.LogEntryKind[source]

Bases: enumfields.enums.Enum

class shoop.utils.analog.BaseLogEntry(*args, **kwargs)[source]

Bases: django.db.models.base.Model

target = None
user
kind

A placeholder class that provides a way to set the attribute on the model.

extra

A placeholder class that provides a way to set the attribute on the model.

class Meta[source]

Bases: object

abstract = False
BaseLogEntry.get_kind_display(*moreargs, **morekwargs)
BaseLogEntry.get_next_by_created_on(*moreargs, **morekwargs)
BaseLogEntry.get_previous_by_created_on(*moreargs, **morekwargs)
shoop.utils.analog.define_log_model(model_class)[source]
shoop.utils.dates module
shoop.utils.dates.parse_date(value)[source]

Tries to make a date out of the value. If impossible, it raises an exception.

Parameters:value – A value of some ilk.
Returns:Date
Return type:datetime.date
Raises ValueError:
 
shoop.utils.dates.parse_time(value)[source]

Tries to make a time out of the value. If impossible, it raises an exception.

Parameters:value – A value of some ilk.
Returns:Time
Return type:datetime.time
Raises ValueError:
 
shoop.utils.dates.try_parse_date(value)[source]

Tries to make a time out of the value. If impossible, returns None.

Parameters:value – A value of some ilk.
Returns:Date
Return type:datetime.date
shoop.utils.dates.try_parse_time(value)[source]

Tries to make a time out of the value. If impossible, returns None.

Parameters:value – A value of some ilk.
Returns:Time
Return type:datetime.time
shoop.utils.decorators module
shoop.utils.decorators.non_reentrant(func)[source]
shoop.utils.excs module
exception shoop.utils.excs.Problem(message, title=None)[source]

Bases: Exception

User-visible exception

message

Append a link to this Problem and return itself.

This API is designed after Exception.with_traceback(), so you can fluently chain this in a raise statement:

raise Problem("Oops").with_link("...", "...")
Parameters:
  • url (str) – URL string
  • title (str) – Title text
Returns:

This same Problem

Return type:

shoop.utils.excs.Problem

exception shoop.utils.excs.ExceptionalResponse(response)[source]

Bases: Exception

shoop.utils.excs.extract_messages(obj_list)[source]

Extract “messages” from a list of exceptions or other objects.

For ValidationErrors, messages are flattened into the output. For Exceptions, args[0] is added into the output. For other objects, force_text is called.

Parameters:obj_list (Iterable[object]) – List of exceptions etc.
Return type:Iterable[str]
shoop.utils.fields module
class shoop.utils.fields.RelaxedModelChoiceField(queryset, empty_label='---------', cache_choices=None, required=True, widget=None, label=None, initial=None, help_text='', to_field_name=None, limit_choices_to=None, *args, **kwargs)[source]

Bases: django.forms.models.ModelChoiceField

to_python(value)[source]
shoop.utils.filer module
shoop.utils.filer.filer_folder_from_path(path)[source]

Split path by slashes and create a hierarchy of Filer Folder objects accordingly. Blank path components are ignored, so “/////foo//////bar///” is the same as “foo/bar”.

The empty string (and None) are handled as “no folder”, i.e. root folder.

Parameters:path (str|None) – Pathname or None
Returns:Folder
Return type:filer.models.Folder
shoop.utils.filer.filer_file_from_upload(request, path, upload_data, sha1=None)[source]

Create a filer.models.filemodels.File from an upload (UploadedFile or such). If the sha1 parameter is passed and a file with said SHA1 is found, it will be returned instead.

Parameters:
  • request (django.http.request.HttpRequest|None) – Request, to figure out the owner for this file
  • path (basestring|filer.models.Folder) – Pathname string (see filer_folder_from_path) or a Filer Folder.
  • upload_data (django.core.files.base.File) – Upload data
  • sha1 (basestring) – SHA1 checksum. If given and a matching model with the SHA1 is found, it is returned instead.
Return type:

filer.models.filemodels.File

shoop.utils.filer.filer_image_from_upload(request, path, upload_data, sha1=None)[source]

Create a Filer Image from an upload (UploadedFile or such). If the sha1 parameter is passed and an Image with said SHA1 is found, it will be returned instead.

Parameters:
  • request (django.http.request.HttpRequest|None) – Request, to figure out the owner for this file
  • path (basestring|filer.models.Folder) – Pathname string (see filer_folder_from_path) or a Filer Folder.
  • upload_data (django.core.files.base.File) – Upload data
  • sha1 (basestring) – SHA-1 checksum of the data, if available, to do deduplication
Return type:

filer.models.imagemodels.Image

shoop.utils.filer.filer_image_from_data(request, path, file_name, file_data, sha1=None)[source]

Create a Filer Image from the given data string. If the sha1 parameter is passed and True (the value True, not a truey value), the SHA-1 of the data string is calculated and passed to the underlying creation function. If the sha1 parameter is truthy (generally the SHA-1 hex string), it’s passed directly to the creation function.

Parameters:
  • request (django.http.request.HttpRequest|None) – Request, to figure out the owner for this file
  • path (basestring|filer.models.Folder) – Pathname string (see filer_folder_from_path) or a Filer Folder.
  • file_name – File name
  • file_data (bytes) – Upload data
  • sha1 (basestring|bool) – SHA-1 checksum of the data, if available, to do deduplication. May also be True to calculate the SHA-1 first.
Return type:

filer.models.imagemodels.Image

shoop.utils.form_group module
exception shoop.utils.form_group.FormInstantiationAttributeError[source]

Bases: Exception

AttributeErrors occurring within the forms property are transmogrified into these.

class shoop.utils.form_group.FormDef(name, form_class, required=True, kwargs=None)[source]

Bases: object

instantiate(prefix, group_initial=None, **extra_kwargs)[source]
class shoop.utils.form_group.FormGroup(data=None, files=None, auto_id='id_%s', prefix=None, initial=None)[source]

Bases: object

add_form_def(name, form_class, required=True, kwargs=None)[source]
instantiate_forms()[source]
forms
full_clean()[source]
errors

Returns an ErrorDict for the data provided for the form

is_valid()[source]
shoop.utils.forms module
shoop.utils.forms.merged_initial_and_data(form)[source]
shoop.utils.forms.get_effective_form_data(form)[source]

Return ‘effective’ data for the form, in essence running its validation methods, but trying to return its state to what it was before the full_clean. Not fool- proof, but what in this universe is.

Returns:data dict
shoop.utils.forms.fill_model_instance(instance, data)[source]

Fill whatever fields possible in instance using the data dict. :param instance: :param data:

shoop.utils.http module
shoop.utils.http.retry_request(n_retries=5, **kwargs)[source]

Retry a requests request with exponential backoff up to n_retries times.

Parameters:
  • n_retries (int) – Maximum retries
  • kwargs – Kwargs to pass to requests.request().
Returns:

Requests response.

Return type:

requests.Response

shoop.utils.i18n module
shoop.utils.i18n.get_babel_locale(locale_string)[source]

Parse a Django-format (dash-separated) locale string and return a Babel locale.

This function is decorated with lru_cache, so executions should be cheap even if babel.Locale.parse() most definitely is not.

Parameters:locale_string (str) – A locale string (“en-US”, “fi-FI”, “fi”)
Returns:Babel Locale
Return type:babel.Locale
shoop.utils.i18n.get_current_babel_locale(fallback='en-US-POSIX')[source]

Get a Babel locale based on the thread’s locale context.

Parameters:fallback – Locale to fallback to; set to None to raise an exception instead.
Returns:Babel Locale
Return type:babel.Locale
shoop.utils.i18n.format_percent(value, digits=0)[source]
shoop.utils.i18n.format_money(amount, digits=None, widen=0, locale=None)[source]

Format a Money object in the given locale.

If neither digits or widen is passed, the preferred number of digits for the amount’s currency is used.

Parameters:
  • amount (Money) – The Money object to format
  • digits (int|None) – How many digits to format the currency with.
  • widen (int|None) – How many digits to widen any existing decimal width with.
  • locale (Locale|str) – Locale object or locale identifier
Returns:

Formatted string

Return type:

str

shoop.utils.i18n.get_language_name(language_code)[source]

Get a language’s name in the currently active locale.

Parameters:language_code (str) – Language code (possibly with an added script suffix (zh_Hans, zh-Hans))
Returns:The language name, or the code if the language couldn’t be derived.
Return type:str
shoop.utils.i18n.javascript_catalog_all(request, domain='djangojs')[source]

Get JavaScript message catalog for all apps in INSTALLED_APPS.

shoop.utils.importing module
shoop.utils.importing.load(specification, context_explanation='Load')[source]
shoop.utils.importing.clear_load_cache()[source]
shoop.utils.importing.cached_load(setting_name, default_value=None)[source]
shoop.utils.iterables module
shoop.utils.iterables.first(iterable, default=None)[source]

Get the first item from the iterable, if possible, or return default.

The iterable is, naturally, iterated for one value.

Parameters:
  • iterable (Iterable) – An iterable.
  • default (object) – Default value
Returns:

The first item from the iterable, or default

Return type:

object

shoop.utils.iterables.batch(iterable, count)[source]

Yield batches of count items from the given iterable.

>>> tuple(x for x in batch([1, 2, 3, 4, 5, 6, 7], 3))
([1, 2, 3], [4, 5, 6], [7])
Parameters:
  • iterable (Iterable) – An iterable
  • count (int) – Number of items per batch. If <= 0, nothing is yielded.
Returns:

Iterable of lists of items

Return type:

Iterable[list[object]]

shoop.utils.models module
shoop.utils.models.get_data_dict(obj)[source]
shoop.utils.models.copy_model_instance(obj)[source]
shoop.utils.money module
class shoop.utils.money.Money[source]

Bases: shoop.utils.numbers.UnitedDecimal

Money value with currency.

The pure decimal value is available from the base classes value property (preferred way) or by casting to Decimal.

Money objects with different currencies cannot be compared or calculated with and will raise UnitMixupError.

See __new__.

classmethod from_data(value, currency)[source]
unit_matches_with(other)[source]
new(value)[source]
shoop.utils.multilanguage_model_form module
shoop.utils.multilanguage_model_form.to_language_codes(languages)[source]
class shoop.utils.multilanguage_model_form.MultiLanguageModelForm(**kwargs)[source]

Bases: parler.forms.TranslatableModelForm

base_fields = OrderedDict()
save(commit=True)[source]
declared_fields = OrderedDict()
media
pre_master_save(instance)[source]
shoop.utils.numbers module
shoop.utils.numbers.bankers_round(value, ndigits=0)[source]
shoop.utils.numbers.strip_non_float_chars(s)[source]

Strips characters that aren’t part of normal floats.

shoop.utils.numbers.parse_decimal_string(s)[source]

Parse decimals with “best effort”.

Parses a string (or unicode) that may be embellished with spaces and other weirdness into the most probable Decimal.

Parameters:s (str) – Input value
Returns:Decimal
Return type:Decimal
shoop.utils.numbers.try_parse_decimal_string(s)[source]
shoop.utils.numbers.get_string_sort_order(s)[source]

Return a sorting order value for a string that contains a garment size.

Parameters:s (str) – Input value (string or number)
Returns:Sorting tuple
Return type:tuple
class shoop.utils.numbers.UnitedDecimal

Bases: decimal.Decimal

Decimal with unit.

Allows creating decimal classes that cannot be mixed, e.g. to prevent operations like:

TaxfulPrice(1) + TaxlessPrice(2)

where TaxfulPrice and TaxlessPrice are subclasses of UnitedDecimal.

copy_negate(*args, **kwargs)[source]
new(value)[source]

Create new instance with given value using same unit as self.

Post-condition: If x = y.new(v), then x.unit_matches_with(y) and x.value == v.

Returns:Object with same type as self and matching unit, but with given decimal value
Return type:UnitedDecimal
quantize(exp, *args, **kwargs)[source]
unit_matches_with(other)[source]

Test if self and other have matching units.

Return type:bool
value

Value of this decimal without the unit.

Return type:decimal.Decimal
exception shoop.utils.numbers.UnitMixupError(obj1, obj2, msg='Unit mixup')

Bases: TypeError

Invoked operation for UnitedDecimal and object with non-matching unit.

The objects involved are stored in instance variables obj1 and obj2. Former is instance of UnitedDecimal or its subclass and the other could be any object.

Variables:
  • obj1 (UnitedDecimal) – Involved object 1
  • obj2 (Any) – Involved object 2
shoop.utils.objects module
shoop.utils.objects.extract_inner_value(source, attr_chain)[source]

Search for a stored value by recursing through dict keys and attributes. Erroneous/missing keys/attribute names will return None.

Parameters:
  • source – The original object, that either has attributes or is itself a dict.
  • attr_chain (tuple) – A tuple of properly ordered strings, containing the attributes and/or keys to successively obtain.
>>> mydict = {"foo": {"bar": {"thing": 25}}}
>>> extract_inner_value(mydict, ("foo", "bar", "thing"))
25
>>> extract_inner_value(mydict, ("foo", "bar", "unthing"))
>>> bool(extract_inner_value(mydict, ("__getitem__",)))
True
>>> bool(extract_inner_value(mydict, ("__getotem__",)))
False
shoop.utils.objects.compare_partial_dicts(source, comparee)[source]

Compare dicts in a “partial” manner. All key/value pairs in source must exist and be equal to those in comparee.

This differs from a raw == in that keys that do not exist in source may exist in comparee.

Parameters:
  • source (dict) – source dict
  • comparee (dict) – comparee dict
Return type:

bool

Returns:

True or False

shoop.utils.objects.compact(in_obj, none_only=True, deep=True)[source]

Compact iterable by removing falsy values.

Iterable may be a mapping or a list.

By default uses not value to test for falseness, but if none_only is set, will use value is None.

By default, iterables within the iterable are also compacted. This can be controlled by the deep argument.

Parameters:
  • in_obj (Iterable) – The object to compact
  • none_only (bool) – Remove only Nones
  • deep (bool) – Recurse through iterables within in_obj
Returns:

Flattened iterable

Return type:

list|dict

shoop.utils.patterns module
class shoop.utils.patterns.Pattern(pattern_text)[source]

Bases: object

Compile a pattern from the given pattern_text.

Patterns are comma-separated atoms of the forms:

  • * – matches anything
  • text – matched directly
  • min-max – inclusive range matched lexicographically OR as integers if possible
  • wild* – wildcards (asterisks and question marks allowed)

In addition, atoms may be prefixed with to negate them.

For instance, “10-20,!15” would match all strings (or numbers) between 10 and 20, but not 15.

matches(target)[source]

Evaluate this Pattern against the target.

Return type:bool
as_normalized()[source]

Return the pattern’s source text in a “normalized” form.

Return type:str
shoop.utils.patterns.pattern_matches(pattern, target)[source]

Verify that a target string matches the given pattern.

For pattern strings, compiled patterns are cached.

Parameters:
  • pattern (str|Pattern) – The pattern. Either a pattern string or a Pattern instance
  • target (str) – Target string to test against.
Returns:

Whether the test succeeded.

Return type:

bool

shoop.utils.properties module
class shoop.utils.properties.MoneyProperty(value, currency)[source]

Bases: object

Property for a Money amount.

Will return Money objects when the property is being get and accepts Money objects on set. Value and currency are read/written from/to other fields.

Fields are given as locators, that is a string in dotted format, e.g. locator "foo.bar" points to instance.foo.bar where instance is an instance of the class owning the MoneyProperty.

Setting value of this property to a Money object with different currency that is currently set (in the field pointed by the currency locator), will raise an UnitMixupError.

Initialize MoneyProperty with given field locators.

Parameters:
  • value (str) – Locator for value of the Money
  • currency (str) – Locator for currency of the Money
value_class

alias of Money

class shoop.utils.properties.PriceProperty(value, currency, includes_tax, **kwargs)[source]

Bases: shoop.utils.properties.MoneyProperty

Property for Price object.

Similar to MoneyProperty but also has includes_tax field.

Operaters with TaxfulPrice and TaxlessPrice objects.

Initialize PriceProperty with given field locators.

Parameters:
  • value (str) – Locator for value of the Price
  • currency (str) – Locator for currency of the Price
  • includes_tax (str) – Locator for includes_tax of the Price
value_class

alias of Price

class shoop.utils.properties.TaxfulPriceProperty(value, currency)[source]

Bases: shoop.utils.properties.MoneyProperty

Initialize MoneyProperty with given field locators.

Parameters:
  • value (str) – Locator for value of the Money
  • currency (str) – Locator for currency of the Money
value_class

alias of TaxfulPrice

class shoop.utils.properties.TaxlessPriceProperty(value, currency)[source]

Bases: shoop.utils.properties.MoneyProperty

Initialize MoneyProperty with given field locators.

Parameters:
  • value (str) – Locator for value of the Money
  • currency (str) – Locator for currency of the Money
value_class

alias of TaxlessPrice

class shoop.utils.properties.MoneyPropped(*args, **kwargs)[source]

Bases: object

Mixin for transforming MoneyProperty init parameters.

Add this mixin as (first) base for the class that has MoneyProperty properties and this will make its __init__ transform passed kwargs to the fields specified in the MoneyProperty.

shoop.utils.properties.resolve(obj, path)[source]

Resolve a locator path starting from object obj.

shoop.utils.serialization module
class shoop.utils.serialization.ExtendedJSONEncoder(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: django.core.serializers.json.DjangoJSONEncoder

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an OverflowError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (‘, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

default(o)[source]
shoop.utils.settings_doc module
shoop.utils.settings_doc.get_known_settings_documentation(order_by='app', only_changed=False)[source]
shoop.utils.settings_doc.get_known_settings_with_comments()[source]
shoop.utils.setup module
class shoop.utils.setup.Setup(load_from=None)[source]

Bases: object

is_valid_key(key)[source]
commit(source)[source]
values()[source]
get(key, default=None)[source]
getlist(key, default=())[source]
classmethod configure(configure)[source]
shoop.utils.text module
shoop.utils.text.flatten(str, whitespace='-')[source]

Flatten the given text into lowercase ASCII, removing diacriticals etc. Replace runs of whitespace with the given whitespace replacement.

>>> print(flatten("hellö, wörld"))
hello,-world
Parameters:
  • str (str) – The string to massage
  • whitespace (str) – The string to replace whitespace with
Returns:

A flattened string

Return type:

str

shoop.utils.text.identifierify(value, sep='_')[source]

Identifierify the given text (keep only alphanumerics and the given separator(s).

Parameters:
  • value (str) – The text to identifierify
  • sep (str) – The separator(s) to keep
Returns:

An identifierified string

Return type:

str

shoop.utils.text.snake_case(value)[source]

Snake_case the given value (join words with underscores). No other treatment is done; use identifierify for that.

shoop.utils.text.kebab_case(value)[source]

Kebab-case the given value (join words with dashes). No other treatment is done; use identifierify for that.

shoop.utils.text.camel_case(value)[source]

CamelCase the given value (join capitalized words). No other treatment is done; use identifierify for that.

shoop.utils.text.space_case(value)[source]

Space case the given value (join words that may have been otherwise separated with spaces). No other treatment is done; use identifierify for that.

shoop.utils.translation module
shoop.utils.translation.cache_translations(objects, languages=None, meta=None)[source]

Cache translation objects in given languages to the objects in one fell swoop. This will iterate a queryset, if one is passed!

Parameters:
  • objects – List or queryset of Translatable models
  • languages – Iterable of languages to fetch. In addition, all “_current_language”s will be fetched
Returns:

objects

shoop.utils.translation.cache_translations_for_tree(root_objects, languages=None)[source]

Cache translation objects in given languages, iterating MPTT trees.

Parameters:
  • root_objects (Iterable[model]) – List of MPTT models
  • languages (Iterable[str]) – List of languages
Module contents
shoop.utils.update_module_attributes(object_names, module_name)[source]

Update __module__ attribute of objects in module.

Set the __module__ attribute of the objects (resolved by the given object names from the given module name) to module_name.

Use case for this function in Shoop is to hide the actual location of objects imported from private submodules, so that they will show up nicely in the Sphinx generated API documentation. This is done by appending following line to the end of the __init__.py of the main package:

update_module_attributes(__all__, __name__)
Parameters:
  • object_names (Iterable[str]) – Names of the objects to update.
  • module_name (str) – Name of the module where the objects reside and also the new value which will be assigned to __module__ attribute of each object.
class shoop.utils.ShoopUtilsAppConfig(*args, **kwargs)[source]

Bases: shoop.apps.AppConfig

name = 'shoop.utils'
verbose_name = <django.utils.functional.lazy.<locals>.__proxy__ object>
label = 'shoop_utils'
shoop.xtheme package
Subpackages
shoop.xtheme.admin_module package
Submodules
shoop.xtheme.admin_module.views module
class shoop.xtheme.admin_module.views.ActivationForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False)[source]

Bases: django.forms.forms.Form

A very simple form for activating a theme.

base_fields = OrderedDict([('activate', <django.forms.fields.CharField object at 0x7f6556b09908>)])
declared_fields = OrderedDict([('activate', <django.forms.fields.CharField object at 0x7f6556b09908>)])
media
class shoop.xtheme.admin_module.views.ThemeConfigView(**kwargs)[source]

Bases: django.views.generic.edit.FormView

A view for listing and activating themes.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/xtheme/admin/config.jinja'
form_class

alias of ActivationForm

get_context_data(**kwargs)[source]
form_valid(form)[source]
class shoop.xtheme.admin_module.views.ThemeConfigDetailView(**kwargs)[source]

Bases: shoop.admin.utils.views.CreateOrUpdateView

A view for configuring a single theme.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of ThemeSettings

template_name = 'shoop/xtheme/admin/config_detail.jinja'
form_class

alias of Form

context_object_name = 'theme_settings'
add_form_errors_as_messages = True
get_object(queryset=None)[source]
get_theme()[source]

Get the theme object to configure.

Returns:Theme object
Return type:shoop.xtheme.Theme
get_context_data(**kwargs)[source]
get_form(form_class=None)[source]
get_success_url()[source]
Module contents
class shoop.xtheme.admin_module.XthemeAdminModule[source]

Bases: shoop.admin.base.AdminModule

Admin module for Xtheme.

Allows theme activation/deactivation and further configuration.

name = <django.utils.functional.lazy.<locals>.__proxy__ object>
breadcrumbs_menu_entry = <shoop.admin.base.MenuEntry object>
get_urls()[source]
get_menu_category_icons()[source]
get_menu_entries(request)[source]
get_notifications(request)[source]
shoop.xtheme.plugins package
Submodules
shoop.xtheme.plugins.consts module
shoop.xtheme.plugins.consts.FALLBACK_LANGUAGE_CODE = '*'

The pseudo-language code used by TranslatedFields and the relevant Plugin API to mark the untranslated/fallback content

shoop.xtheme.plugins.forms module
class shoop.xtheme.plugins.forms.PluginForm(**kwargs)[source]

Bases: django.forms.forms.Form

Base class for plugin configuration forms.

populate()[source]
get_config()[source]

Get the new config dict for a plugin.

Called when the form is valid, akin to django.forms.models.ModelForm.save.

The default implementation just augments the old config with the cleaned data for the form.

Returns:A new JSONable (!) config dict
Return type:dict
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.xtheme.plugins.forms.GenericPluginForm(**kwargs)[source]

Bases: shoop.xtheme.plugins.forms.PluginForm

A generic form for Xtheme plugins; populates itself based on fields in the plugin class.

populate()[source]
base_fields = OrderedDict()
declared_fields = OrderedDict()
media
class shoop.xtheme.plugins.forms.TranslatableField(*args, **kwargs)[source]

Bases: django.forms.fields.Field

widget

alias of TranslatableFieldWidget

clean(value)[source]
shoop.xtheme.plugins.text module
class shoop.xtheme.plugins.text.TextPlugin(config)[source]

Bases: shoop.xtheme.Plugin

Very basic Markdown rendering plugin.

Instantiate a Plugin with the given config dictionary.

Parameters:config (dict) – Dictionary of freeform configuration data
identifier = 'text'
name = 'Text'
fields = [('text', <shoop.xtheme.plugins.forms.TranslatableField object at 0x7f65560a1160>)]
render(context)[source]
shoop.xtheme.plugins.widgets module
class shoop.xtheme.plugins.widgets.TranslatableFieldWidget(languages, input_widget=<class 'django.forms.widgets.TextInput'>, attrs=None)[source]

Bases: django.forms.widgets.Widget

render(name, value, attrs=None)[source]
id_for_label(id_)[source]
value_from_datadict(data, files, name)[source]
format_output(widget_pairs)[source]
decompress(value)[source]
media
Module contents
shoop.xtheme.templatetags package
Submodules
shoop.xtheme.templatetags.xtheme_tags module
Module contents
shoop.xtheme.views package
Submodules
shoop.xtheme.views.command module
shoop.xtheme.views.command.handle_command(request, command)[source]

Internal dispatch function.

Parameters:
Returns:

A response

Return type:

django.http.HttpResponse

shoop.xtheme.views.command.command_dispatch(request)[source]

Xtheme command dispatch view.

Parameters:request (django.http.HttpRequest) – A request
Returns:A response
Return type:django.http.HttpResponse
shoop.xtheme.views.editor module
class shoop.xtheme.views.editor.EditorView(**kwargs)[source]

Bases: django.views.generic.base.TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

template_name = 'shoop/xtheme/editor.jinja'
xtheme_injection = False
changed = False
get_context_data(**kwargs)[source]
dispatch(request, *args, **kwargs)[source]
post(request, *args, **kwargs)[source]
build_form()[source]
save_layout(layout=None)[source]
dispatch_add_cell(y, **kwargs)[source]
dispatch_add_row(y=None, **kwargs)[source]
dispatch_del_row(y, **kwargs)[source]
dispatch_del_cell(x, y, **kwargs)[source]
dispatch_change_plugin(plugin='', **kwargs)[source]
dispatch_publish(**kwargs)[source]
dispatch_revert(**kwargs)[source]
shoop.xtheme.views.extra module
shoop.xtheme.views.extra.clear_view_cache(**kwargs)[source]
shoop.xtheme.views.extra.get_view_by_name(theme, view_name)[source]
shoop.xtheme.views.extra.extra_view_dispatch(request, view)[source]

Dispatch to an Xtheme extra view.

Parameters:
Returns:

A response of some ilk

Return type:

django.http.HttpResponse

shoop.xtheme.views.forms module
class shoop.xtheme.views.forms.LayoutCellGeneralInfoForm(**kwargs)[source]

Bases: django.forms.forms.Form

CELL_FULL_WIDTH = 12
CELL_WIDTH_CHOICES = [(12, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70470>), (9, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70978>), (8, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70a90>), (6, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70ac8>), (4, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70b38>), (3, <django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f655ca70ba8>)]
populate()[source]

Populate the form with fields for size and plugin selection.

save()[source]

Save size configuration. Plugin configuration is done via JavaScript POST.

Both breakpoints (sm`and `md) are set to same value defined in cell_width_field. The reason for this is that the difference between these breakpoints is so minor that manually assigning both of these by shop admin introduces too much complexity to row-cell management UI.

base_fields = OrderedDict([('plugin', <django.forms.fields.ChoiceField object at 0x7f655ca702b0>)])
declared_fields = OrderedDict([('plugin', <django.forms.fields.ChoiceField object at 0x7f655ca702b0>)])
media
class shoop.xtheme.views.forms.LayoutCellFormGroup(**kwargs)[source]

Bases: shoop.utils.form_group.FormGroup

Form group containing the LayoutCellGeneralInfoForm and a possible plugin-dependent configuration form.

save()[source]
Module contents
Submodules
shoop.xtheme.editing module
shoop.xtheme.editing.could_edit(request)[source]

Return true if the context of the given request would allow Xtheme editing.

Parameters:request (django.http.HttpRequest) – HTTP request
Returns:Would allow editing?
Return type:bool
shoop.xtheme.editing.is_edit_mode(request)[source]

Return true if the given request has xtheme editing enabled.

Parameters:request (django.http.HttpRequest) – HTTP request
Returns:In edit mode?
Return type:bool
shoop.xtheme.editing.set_edit_mode(request, flag)[source]

Enable or disable edit mode for the request.

Parameters:
shoop.xtheme.editing.may_inject(context)[source]

Figure out if we may inject Xtheme editing into this view.

The requirements are that there is a CBV view object in the context, and that view object does not explicitly opt-out of editing with xtheme_injection = False

Parameters:context (jinja2.runtime.Context) – Jinja rendering context
Returns:Permission bool
Return type:bool
shoop.xtheme.editing.add_edit_resources(context)[source]

Possibly inject Xtheme editor injection resources into the given context’s resources.

Parameters:context (jinja2.runtime.Context) – Jinja rendering context
shoop.xtheme.engine module
class shoop.xtheme.engine.XthemeTemplate[source]

Bases: jinja2.environment.Template

A subclass of Jinja templates with additional post-processing magic.

render(*args, **kwargs)[source]

Render the template and postprocess it.

Returns:Rendered markup
Return type:str
class shoop.xtheme.engine.XthemeEnvironment(block_start_string='{%', block_end_string='%}', variable_start_string='{{', variable_end_string='}}', comment_start_string='{#', comment_end_string='#}', line_statement_prefix=None, line_comment_prefix=None, trim_blocks=False, lstrip_blocks=False, newline_sequence='n', keep_trailing_newline=False, extensions=(), optimized=True, undefined=<class 'jinja2.runtime.Undefined'>, finalize=None, autoescape=False, loader=None, cache_size=400, auto_reload=True, bytecode_cache=None)[source]

Bases: jinja2.environment.Environment

Overrides the usual template class and allows dynamic switching of Xthemes.

Enable by adding "environment": "shoop.xtheme.engine.XthemeEnvironment" in your TEMPLATES settings.

template_class

alias of XthemeTemplate

get_template(name, parent=None, globals=None)[source]

Load a template from the loader. If a loader is configured this method asks the loader for the template and returns a Template.

Parameters:
  • name (str) – Template name.
  • parent (str|None) – If the parent parameter is not None, join_path is called to get the real template name before loading.
  • globals (dict|None) – The globals parameter can be used to provide template wide globals. These variables are available in the context at render time.
Returns:

Template object

Return type:

shoop.xtheme.engine.XthemeTemplate

get_or_select_template(template_name_or_list, parent=None, globals=None)[source]

Does a typecheck and dispatches to select_template or get_template.

Parameters:
  • template_name_or_list (str|Iterable[str]) – Template name or list
  • parent (str|None) – If the parent parameter is not None, join_path is called to get the real template name before loading.
  • globals – The globals parameter can be used to provide template wide globals. These variables are available in the context at render time.
Returns:

Template object

Return type:

shoop.xtheme.engine.XthemeTemplate

shoop.xtheme.engine.concat()

S.join(iterable) -> str

Return a string which is the concatenation of the strings in the iterable. The separator between elements is S.

shoop.xtheme.forms module
class shoop.xtheme.forms.GenericThemeForm(**kwargs)[source]

Bases: django.forms.models.ModelForm

A generic form for Xthemes; populates itself based on fields in the theme class.

class Meta[source]

Bases: object

model

alias of ThemeSettings

fields = ()
GenericThemeForm.base_fields = OrderedDict()
GenericThemeForm.declared_fields = OrderedDict()
GenericThemeForm.media
GenericThemeForm.save(commit=True)[source]

Save theme settings into the ThemeSettings instance

Parameters:commit (bool) – Commit flag. Ignored, but there for compatibility with the superclass.
Returns:The now saved ThemeSettings instance
Return type:shoop.xtheme.models.ThemeSettings
shoop.xtheme.layout module
class shoop.xtheme.layout.LayoutCell(plugin_identifier, config=None, sizes=None)[source]

Bases: object

A single cell in a layout. Maps to Bootstrap’s col-XX-XX classes.

Initialize a layout cell with a given plugin, config and sizing configuration.

Parameters:
  • plugin_identifier (str) – Plugin identifier string
  • config (dict|None) – Config dict
  • sizes (dict|None) – Size dict
plugin_class

Get the actual plugin class for this cell, or None if the plugin class isn’t available.

Returns:Plugin or None.
Return type:Plugin|None
plugin_name

Get the name of the plugin in this cell for display purposes.

Returns:Plugin name string
Return type:str
instantiate_plugin()[source]

Instantiate the plugin with the current config.

Returns:Instantiated plugin (if a class is available)
Return type:Plugin|None
render(context)[source]

Return the plugin’s rendered contents.

Parameters:context (jinja2.runtime.Context) – Jinja2 rendering context.
Returns:string of content
Return type:str
classmethod unserialize(data)[source]

Unserialize a dict of layout cell data into a new cell.

Parameters:data (dict) – Layout cell data dict
Returns:New cell
Return type:LayoutCell
serialize()[source]

Serialize this cell into a dict.

Returns:Layout cell data dict
Return type:dict
class shoop.xtheme.layout.LayoutRow(cells=None)[source]

Bases: object

A single row in a layout. Maps to Bootstrap’s row class.

Parameters:cells – Optional iterable of LayoutCells to populate this LayoutRow with.
classmethod unserialize(data)[source]

Unserialize a dict of layout row data into a new row, along with all cell children.

Parameters:data (dict) – Layout row data dict
Returns:New row
Return type:LayoutRow
serialize()[source]

Serialize this row into a dict.

Returns:Layout row data dict
Return type:dict
add_cell(sizes=None)[source]

Add an empty cell to this row. Used by the editor API.

Parameters:sizes (dict|None) – An optional size dict, see LayoutCell
Returns:The new layout cell
Return type:LayoutCell
class shoop.xtheme.layout.Layout(placeholder_name, rows=None)[source]

Bases: object

The layout (row, cell and plugin configuration) for a single placeholder.

Parameters:
  • placeholder_name (str|None) – The name of the placeholder. Could be None.
  • rows (Iterable[LayoutRow]|None) – Optional iterable of LayoutRows to populate this Layout with.
row_class = 'row'
cell_class_template = 'col-%(breakpoint)s-%(width)s'
hide_cell_class_template = 'hidden-%(breakpoint)s'
classmethod unserialize(data, placeholder_name=None)[source]

Unserialize a dict of layout data into a new layout, with all rows and cells.

Parameters:
  • data (dict) – Layout data dict
  • placeholder_name (str) – Placeholder name if none is specified in the data
Returns:

New layout

Return type:

Layout

serialize()[source]

Serialize this layout into a dict.

Returns:Layout data dict
Return type:dict
begin_row()[source]

Begin a new row in the layout.

This is internally used by LayoutPartExtension, but could just as well be used to programmatically create layouts for whichever purpose.

Returns:The newly created row
Return type:LayoutRow
begin_column(sizes=None)[source]

Begin a new column (cell) in the layout, in the last row.

If no rows exist, one is implicitly created, for your convenience. The newly created cell has no plugin or configuration.

This is internally used by LayoutPartExtension, but could just as well be used to programmatically create layouts for whichever purpose.

Parameters:sizes – The size dictionary to pass to LayoutCell.
Returns:The newly created cell
Return type:LayoutCell
add_plugin(plugin_identifier, config)[source]

Configure a plugin in the last row and cell of the layout.

If no rows or cells exist, one row and one cell is implicitly created.

This is internally used by LayoutPartExtension, but could just as well be used to programmatically create layouts for whichever purpose.

Parameters:
  • plugin_identifier (str) – Plugin identifier string
  • config (dict) – Configuration dict
Returns:

The configured cell

Return type:

LayoutCell

get_cell(x, y)[source]

Get a layout cell indicated by the given (zero-based) coordinates.

If the coordinates are out of range, returns None.

Parameters:
  • x (int) – X (horizontal) coordinate
  • y (int) – Y (vertical) coordinate
Returns:

Layout cell

Return type:

LayoutCell|None

insert_row(y=None)[source]

Insert a new row at the given zero-based row and return it.

If y is None, the row in inserted at the end.

Parameters:y (int) – Y coordinate
Returns:The new layout row
Return type:LayoutRow
delete_row(y)[source]

Delete the y’th (zero-based) row.

If y is out of bounds, nothing is done.

Parameters:y (int) – Y coordinate
Returns:Was something done?
Return type:bool
delete_cell(x, y)[source]

Delete a layout cell indicated by the given (zero-based) coordinates.

If the coordinates are out of range, nothing is done.

Parameters:
  • x (int) – X (horizontal) coordinate
  • y (int) – Y (vertical) coordinate
Returns:

Was something done?

Return type:

bool

shoop.xtheme.models module
class shoop.xtheme.models.SavedViewConfigQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: django.db.models.query.QuerySet

appropriate(theme, view_name, draft)[source]

Get an “appropriate” SavedViewConfig for the parameters given.

When draft mode is off:

  • A PUBLIC SavedViewConfig is returned, or a new one in CURRENT_DRAFT status.

When draft mode is on:

  • A CURRENT_DRAFT SavedViewConfig is returned, if one exists.
  • If a PUBLIC SavedViewConfig exists, its data is copied into a new, unsaved CURRENT_DRAFT SavedViewConfig.
Parameters:
Returns:

SavedViewConfig (possibly not saved)

Return type:

SavedViewConfig

class shoop.xtheme.models.SavedViewConfigStatus[source]

Bases: enumfields.enums.Enum

Stati for SavedViewConfigs.

The lifecycle for SavedViewConfigs (SVCs) for a given (theme, view) pair is as follows:

  • Initially, there’s zero SVCs.
  • When a placeholder layout is saved in edit mode, an SVC in the CURRENT_DRAFT status is saved.
  • When an SVC in CURRENT_DRAFT status is published, all other SVCs for the theme/view pair are “demoted” to being OLD_VERSIONs and the CURRENT_DRAFT SVC is promoted to being the PUBLIC one (and there should always be zero or one PUBLIC SavedViewConfigs per (theme, view) pair).
  • When an SVC in CURRENT_DRAFT status is reverted, it is simply deleted.
  • When an SVC has been published and edit mode is entered again, the current PUBLIC SVC is copied into a new CURRENT_DRAFT version.
class shoop.xtheme.models.SavedViewConfig(id, theme_identifier, view_name, created_on, status, _data)[source]

Bases: django.db.models.base.Model

status

A placeholder class that provides a way to set the attribute on the model.

objects = <django.db.models.manager.ManagerFromSavedViewConfigQuerySet object>
draft
publish()[source]
revert()[source]
set_layout_data(placeholder_name, layout)[source]
get_layout_data(placeholder_name)[source]
clear_layout_data(placeholder_name)[source]
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception SavedViewConfig.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

SavedViewConfig.get_next_by_created_on(*moreargs, **morekwargs)
SavedViewConfig.get_previous_by_created_on(*moreargs, **morekwargs)
SavedViewConfig.get_status_display(*moreargs, **morekwargs)
class shoop.xtheme.models.ThemeSettings(id, theme_identifier, active, data)[source]

Bases: django.db.models.base.Model

data

A placeholder class that provides a way to set the attribute on the model.

activate()[source]
get_setting(key, default=None)[source]
get_settings()[source]
update_settings(update_values)[source]
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception ThemeSettings.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

ThemeSettings.objects = <django.db.models.manager.Manager object>
shoop.xtheme.parsing module
exception shoop.xtheme.parsing.Unflattenable[source]

Bases: Exception

Exception raised when a node list can’t be flattened into a constant.

exception shoop.xtheme.parsing.NonConstant[source]

Bases: ValueError

Exception raised when something expected to be constant... is not.

exception shoop.xtheme.parsing.NestingError[source]

Bases: ValueError

Exception raised when a template’s placeholder/column/row/plugin hierarchy is out of whack.

shoop.xtheme.parsing.flatten_const_node_list(environment, node_list)[source]

Try to flatten the given node list into a single string.

Parameters:
  • environment (jinja2.environment.Environment) – Jinja2 environment
  • node_list (list[jinja2.nodes.Node]) – List of nodes
Returns:

String of content

Return type:

str

Raises Unflattenable:
 

Raised when the node list can’t be flattened into a constant

shoop.xtheme.parsing.parse_constantlike(environment, parser)[source]

Parse the next expression as a “constantlike” expression.

Expression trees that fold into constants are constantlike, as are bare variable names.

Parameters:
  • environment (jinja2.environment.Environment) – Jinja2 environment
  • parser (jinja2.parser.Parser) – Template parser
Returns:

constant value of any type

Return type:

object

shoop.xtheme.parsing.noop_node(lineno)[source]

Return a no-op node (compiled into a single 0).

Parameters:lineno (int) – Line number for the node
Returns:Node
Return type:jinja2.nodes.ExprStmt
class shoop.xtheme.parsing.PlaceholderExtension(environment)[source]

Bases: shoop.xtheme.parsing._PlaceholderManagingExtension

PlaceholderExtension manages {% placeholder <NAME> %} ... {% endplaceholder %}.

  • The name can be any Jinja2 expression that can be folded into a constant, with the addition of bare variable names such as name meaning the same as "name". This makes it slightly easier to write templates.
  • The body of this block is actually discarded; only the inner column, row and plugin directives have any meaning. (A parser-time Layout object is created and populated during parsing of this block.)
tags = {'placeholder'}
parse(parser)[source]

Parse a placeholder!

Parameters:parser (jinja2.parser.Parser) – Template parser
Returns:Output node for rendering a placeholder.
Return type:jinja2.nodes.Output
identifier = 'shoop.xtheme.parsing.PlaceholderExtension'
class shoop.xtheme.parsing.LayoutPartExtension(environment)[source]

Bases: shoop.xtheme.parsing._PlaceholderManagingExtension

Parser for row and column tags.

Syntax for the row and column tags is:

{% row %}
    {% column [SIZES] %}...{% endcolumn %}
{% endrow %}
  • Rows map to LayoutRow objects and columns map to LayoutCell.
  • For a single-cell layout, these are not necessary. {% plugin %} invocations without preceding {% row %}/{% column %} directives imply a single row and a single column.
tags = {'column', 'row'}
parse(parser)[source]

Parse a column or row.

Parameters:parser (jinja2.parser.Parser) – Template parser
Returns:A null output node.
Return type:jinja2.nodes.Node
identifier = 'shoop.xtheme.parsing.LayoutPartExtension'
class shoop.xtheme.parsing.PluginExtension(environment)[source]

Bases: shoop.xtheme.parsing._PlaceholderManagingExtension

Parser for plugin tags.

Syntax for plugin tag is:

{% plugin <NAME> %}...{% endplugin %}
  • The (optional) body of the plugin block is expected to be a Jinja2 AST that can be folded into a constant. Generally this means a single block of text ({% raw }/{% endraw %} is okay!).
  • The contents of the body, if set, must be valid TOML markup. The TOML is parsed during Jinja2 parse time into a dict, which in turn is folded into the layout description object. This means only the initial parsing of the template incurs whatever performance hit there is in parsing TOML; the Jinja2 bccache should take care of the rest.
tags = {'plugin'}
parse(parser)[source]

Parse a column or row.

Parameters:parser (jinja2.parser.Parser) – Template parser
Returns:A null output node.
Return type:jinja2.nodes.Node
identifier = 'shoop.xtheme.parsing.PluginExtension'
shoop.xtheme.rendering module
shoop.xtheme.rendering.get_view_config(context)[source]

Get a view configuration object for a Jinja2 rendering context.

Parameters:context (jinja2.runtime.Context) – Rendering context
Returns:View config
Return type:shoop.xtheme.view_config.ViewConfig
shoop.xtheme.rendering.render_placeholder(context, placeholder_name, default_layout=None, template_name=None)[source]

Render a placeholder in a given context.

See PlaceholderRenderer for argument docs.

Returns:Markup
Return type:Markup
class shoop.xtheme.rendering.PlaceholderRenderer(context, placeholder_name, default_layout=None, template_name=None)[source]

Bases: object

Main class for materializing a placeholder’s contents during template render time.

Parameters:
  • context (jinja2.runtime.Context) – Rendering context
  • placeholder_name (str) – Placeholder name
  • default_layout (Layout|dict|None) – Layout or serialized layout (from template configuration)
  • template_name (str|None) – The actual template this node was in. Used to figure out whether the placeholder lives in an extends parent, or in a child.
render()[source]

Get this placeholder’s rendered contents.

Returns:Rendered markup.
Return type:markupsafe.Markup
shoop.xtheme.resources module
class shoop.xtheme.resources.InlineScriptResource[source]

Bases: str

An inline script resource (a subclass of string).

The contents are rendered inside a <script> tag.

classmethod from_vars(var_name, *args, **kwargs)[source]

Create an InlineScriptResource assigning an object of variables into a name in the window scope.

Aside from var_name the signature of this function is similar to that of dict. Useful for configuration options, etc.

Parameters:var_name (str) – The variable to add into global scope
Returns:An InlineScriptResource object
Return type:InlineScriptResource
class shoop.xtheme.resources.InlineMarkupResource[source]

Bases: str

An inline markup resource (a subclass of string).

The contents are rendered as-is.

class shoop.xtheme.resources.ResourceContainer[source]

Bases: object

ResourceContainers deal with storing and rendering injected resources.

A ResourceContainer is injected into rendering contexts by XthemeTemplate (akin to how django-jinja‘s Template injects request and csrf_token).

add_resource(location, resource)[source]

Add a resource into the given location.

Duplicate resources are ignored (and false is returned). Resource injection order is retained.

Parameters:
  • location (str) – The name of the location. See KNOWN_LOCATIONS.
  • resource (str|InlineMarkupResource|InlineScriptResource) – The actual resource. Either an URL string or one of the inline resource classes.
Returns:

Success flag.

Return type:

bool

render_resources(location, clean=True)[source]

Render the resources for the given location, then (by default) clean that list of resources.

Parameters:
  • location (str) – The name of the location. See KNOWN_LOCATIONS.
  • clean (bool) – Whether or not to clean up the list of resources.
Returns:

String of HTML

shoop.xtheme.resources.inject_resources(context, content, clean=True)[source]

Inject all the resources in the context’s ResourceContainer into appropriate places in the content given.

Parameters:
  • context (jinja2.runtime.Context) – Rendering context
  • content (str) – HTML content
  • clean (bool) – Clean the resource container as we go?
Returns:

Possibly modified HTML content

Return type:

str

shoop.xtheme.resources.get_resource_container(context)[source]

Get a ResourceContainer from a rendering context.

Parameters:context (jinja2.runtime.Context) – Context
Returns:Resource Container
Return type:shoop.xtheme.resources.ResourceContainer|None
shoop.xtheme.resources.add_resource(context, location, resource)[source]

Add an Xtheme resource into the given context.

Parameters:
  • context (jinja2.runtime.Context) – Context
  • location (str) – Location string (see KNOWN_LOCATIONS)
  • resource (str|InlineMarkupResource|InlineScriptResource) – Resource descriptor (URL or inline markup object)
Returns:

Success flag

Return type:

bool

shoop.xtheme.template_ns module
class shoop.xtheme.template_ns.XthemeNamespace[source]

Bases: object

A template helper namespace for Xtheme-related functionality.

get_view_name(context)[source]

Get the current view’s view name (used for identifying view configurations).

Parameters:context (jinja2.runtime.Context) – Implicit Jinja2 context
Returns:View name string
Return type:str
is_edit_mode(context)[source]

Get the current edit mode status.

Parameters:context (jinja2.runtime.Context) – Implicit Jinja2 context
Returns:Edit mode enable flag
Return type:bool
get(context, name, default=None)[source]

Get a theme setting value.

Parameters:
  • context (jinja2.runtime.Context) – Implicit Jinja2 context
  • name (str) – Setting name
  • default (object) – Default value if setting is not found
Returns:

Value

Return type:

object

shoop.xtheme.testing module
shoop.xtheme.testing.override_current_theme_class(theme_class=<object object>)

Context manager for overriding the currently active theme class for testing.

An instance of this class is then returned by get_current_theme.

A falsy value means None is returned from get_current_theme, which is also useful for testing.

Parameters:theme_class (class[Theme]) – A theme class object
shoop.xtheme.urls module
shoop.xtheme.utils module
shoop.xtheme.utils.join_css_classes(class_list)[source]

Join an iterable of truthy values by spaces, effectively creating a list of CSS classes.

The retval is sorted for cleanliness.

Parameters:class_list (Iterable[str]) – Iterable of classes
Returns:String
Return type:str
shoop.xtheme.utils.get_html_attrs(attrs)[source]

Flatten a dict into HTML attributes (it’s django.forms.utils.flatatt on steroids!).

Only truthy keys and values are taken into account; list-like values are flattened with join_css_classes

Parameters:attrs (dict[str, object]) – Attribute dict
Returns:string ready to paste after a HTML tag open. <foo%s>!
Return type:str
shoop.xtheme.view_config module
class shoop.xtheme.view_config.ViewConfig(theme, view_name, draft)[source]

Bases: object

A view configuration.

Contains layout and plugin configuration for all placeholders in a given view.

This class does not directly correspond to a database model; it may act as a container for SavedViewConfig objects, and wraps the SavedViewConfig API.

Initialize a view configuration.

Parameters:
  • theme (shoop.xtheme.Theme|None) – Theme object (could be None to not touch the database)
  • view_name (str) – View name (the class name of the view)
  • draft (bool) – Load in draft mode?
saved_view_config

Get a saved view config model depending on the current parameters.

Returns:A SavedViewConfig object for the current theme/view/draft mode, or None
Return type:shoop.xtheme.models.SavedViewConfig|None
get_placeholder_layout(placeholder_name, default_layout=None)[source]

Get a Layout object for the given placeholder.

Parameters:
  • placeholder_name (str) – The name of the placeholder to load.
  • default_layout (dict|Layout) – Default layout configuration (either a dict or an actual Layout)
Returns:

Layout

Return type:

Layout

save_default_placeholder_layout(placeholder_name, layout)[source]

Save a default placeholder layout (only if no data for the PH already exists).

Parameters:
  • placeholder_name (str) – Placeholder name
  • layout (Layout|dict) – Layout or layout data
Returns:

True if saved

Return type:

bool

publish()[source]

Publish this revision of the view configuration as the currently public one.

Returns:Success flag
Return type:bool
revert()[source]

Revert this revision of the view configuration, if it’s a draft.

Returns:Success flag
Return type:bool
save_placeholder_layout(placeholder_name, layout)[source]

Save the given layout as the layout for the given placeholder.

Parameters:
  • placeholder_name (str) – The placeholder name.
  • layout (Layout|dict) – Layout object (or dict)
Module contents
class shoop.xtheme.Plugin(config)

Bases: object

A plugin that can be instantiated within a shoop.xtheme.layout.LayoutCell.

Other plugins should inherit from this class and register themselves in the xtheme_plugin provide category.

Instantiate a Plugin with the given config dictionary.

Parameters:config (dict) – Dictionary of freeform configuration data
editor_form_class

alias of GenericPluginForm

fields = []
get_editor_form_class()[source]

Return the form class for editing this plugin.

The form class should either derive from PluginForm, or at least have a get_config() method.

Form classes without fields are treated the same way as if you’d return None, i.e. no configuration form is presented to the user.

Returns:Editor form class
Return type:class[forms.Form]|None
classmethod get_plugin_choices(empty_label=None)[source]

Get a sorted list of 2-tuples (identifier and name) of available Xtheme plugins.

Handy for <select> boxen.

Parameters:empty_label (str|None) – Label for the “empty” choice. If falsy, no empty choice is prepended
Returns:List of 2-tuples
Return type:Iterable[tuple[str, str]]
get_translated_value(key, default=None, language=None)[source]

Get a translated value from the plugin’s configuration.

It’s assumed that translated values are stored in a {language: data, ...} dictionary in the plugin configuration blob. This is the protocol that shoop.xtheme.plugins.forms.TranslatableField uses.

If the configuration blob contains such a dictionary, but it does not contain a translated value in the requested language does not exist, the fallback value, if any, within that dictionary is tried next. Failing that, the default value is returned.

Parameters:
  • key (str) – Configuration key
  • default – Default value to return when all else fails.
  • language (str|None) – Requested language. Defaults to the active language.
Returns:

A translated value.

identifier = None
is_context_valid(context)[source]

Check that the given rendering context is valid for rendering this plugin.

By default, just checks required_context_variables.

Parameters:context (jinja2.runtime.Context) – Rendering context
Returns:True if we should bother trying to render this
Return type:bool
classmethod load(identifier)[source]

Get a plugin class based on the identifier from the xtheme_plugin provides registry.

Parameters:identifier (str) – Plugin class identifier
Returns:A plugin class, or None
Return type:class[Plugin]|None
name = <django.utils.functional.lazy.<locals>.__proxy__ object>
render(context)[source]

Return the HTML for a plugin in a given rendering context.

Parameters:context (jinja2.runtime.Context) – Rendering context
Returns:String of rendered content.
Return type:str
required_context_variables = set()
class shoop.xtheme.TemplatedPlugin(config)

Bases: shoop.xtheme.Plugin

Convenience base class for plugins that just render a “sub-template” with a given context.

Instantiate a Plugin with the given config dictionary.

Parameters:config (dict) – Dictionary of freeform configuration data
config_copied_variables = set()
engine = None
get_context_data(context)[source]

Get a context dictionary from a Jinja2 context.

Parameters:context (jinja2.runtime.Context) – Jinja2 rendering context
Returns:Dict of vars
Return type:dict[str, object]
inherited_variables = set()
render(context)[source]
template_name = ''
class shoop.xtheme.Theme(settings_obj=None)

Bases: object

Base class for all Xtheme themes.

This class does not directly correspond to a database object; it’s used in the rendering, etc. process.

It does, however, act as a container for a ThemeSettings object that contains the actual persisted settings etc.

Initialize this theme, with an optional ThemeSettings object

Parameters:settings_obj (ThemeSettings|None) – A theme settings object for this theme, if one exists. Passing this in will avoid extraneous database queries.
author = ''
fields = []
get_configuration_form(form_kwargs)[source]

Return a ModelForm instance (model=ThemeSettings) for configuring this theme.

By default, returns a GenericThemeForm (a ModelForm populated from theme.fields).

Parameters:form_kwargs (dict) – The keyword arguments that should be used for initializing the form
Return type:django.forms.ModelForm
get_setting(key, default=None)[source]

Get a setting value for this theme.

Parameters:
  • key (str) – Setting name
  • default (object) – Default value, if the setting is not set
Returns:

Setting value

Return type:

object

get_settings()[source]

Get all the currently set settings for the theme as a dict.

Returns:Dict of settings
Return type:dict
get_view(view_name)[source]

Get an extra view for this theme.

Views may be either normal Django functions or CBVs (or anything that has as_view() really). Falsy values are considered “not found”.

Parameters:view_name (str) – View name
Returns:The extra view, if one exists for the given name.
Return type:dict[str, View|callable]|None
global_placeholders = []
identifier = None
name = ''
set_current()[source]

Set this theme as the active theme.

set_setting(key, value)[source]

Set a theme setting key to the value value.

Parameters:
  • key (str) – Setting name
  • value (object) – Setting value
set_settings(*args, **kwargs)[source]

Set a number of settings for this theme.

The arguments are exactly the same as those to dict.

Note

It’s better to call this once than set_setting several times.

settings_obj

Get a saved settings model for this theme. If one does not yet exist, an unsaved one is returned.

If one was passed in the ctor, naturally that one is returned.

Return type:shoop.xtheme.models.ThemeSettings
template_dir = None
shoop.xtheme.get_current_theme(request=None)

Get the currently active theme object.

Parameters:request (HttpRequest|None) – Request, if available
Returns:Theme object or None
Return type:Theme
shoop.xtheme.get_theme_by_identifier(identifier, settings_obj=None)

Get an instantiated theme by identifier.

Parameters:
Returns:

Theme object or None

Return type:

Theme

shoop.xtheme.set_current_theme(identifier)

Activate a theme based on identifier.

Parameters:identifier (str) – Theme identifier
shoop.xtheme.templated_plugin_factory(identifier, template_name, **kwargs)

A factory (akin to modelform_factory) to quickly create simple plugins.

Parameters:
  • identifier (str) – The unique identifier for the new plugin.
  • template_name (str) – The template file path this plugin should render
  • kwargs (dict) – Other arguments for the TemplatedPlugin/Plugin classes.
Returns:

New TemplatedPlugin subclass

Return type:

class[TemplatedPlugin]

Submodules
shoop.configuration module

API for Shoop’s Dynamic Configuration.

Idea of the Dynamic Configuration is to allow storing configuration values similarly as Django settings allows, but in a more flexible way: Dynamic Configuration can be changed with a simple API and there is no need restart the application server after changing a value.

Dynamic configuration values are permanent. Current implementation stores the values with ConfigurationItem model into database, but that may change in the future.

Configuration values are get and set by a key string. There is a global configuration and a shop specific configuration for each shop. Values in shop specific configuration override the values in global configuration.

shoop.configuration.set(shop, key, value)[source]

Set configuration item value for a shop or globally.

If given shop is None, the value of given key is set globally for all shops. Otherwise sets a shop specific value which overrides the global value in configuration of the specified shop.

Parameters:
  • shop (shoop.core.models.Shop|None) – Shop to set value for, or None to set a global value
  • key (str) – Name of the key to set
  • value (Any) – Value to set. Note: Must be JSON serializable.
shoop.configuration.get(shop, key, default=None)[source]

Get configuration value by shop and key.

Global configuration can be accessed with shop=None.

Parameters:
  • shop (shoop.core.models.Shop|None) – Shop to get configuration value for, or None
  • key (str) – Configuration item key
  • default (Any) – Default value returned if no value is set for given key (globally or in given shop).
Returns:

Configuration value or the default value

Return type:

Any

Module contents

Shoop Web APIs

REST API

The Shoop REST API is built on Django REST Framework with additional functionality built on The Provides system to auto-discover available viewsets.

Setting up the Shoop REST API

First, add rest_framework and shoop.api to your INSTALLED_APPS.

Then – and this differs from Django REST Framework’s defaults – you must add the REST_FRAMEWORK configuration dict to your settings. Django REST Framework defaults to no permission checking whatsoever (rest_framework.permissions.AllowAny), which would make all of your data world-readable and writable.

This is not what we want to accidentally happen, so configuration is enforced.

For the sake of demonstration, let’s make the API only accessible for superusers with the IsAdminUser permission policy. (Authentication is enabled by the default settings.)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',)
}

Now just add the API to your root urlconf.

urlpatterns = patterns(
    # *snip*
    url(r'^api/', include('shoop.api.urls')),
    # *snip*
)

All done! If you visit the /api/ URL (as a suitably authenticated user), you should be presented with Django REST Framework’s human-friendly user interface.

REST API Usage Example

This sketch of a script illustrates how to use the Shoop REST API.

# -*- coding: utf-8 -*-
import json
import uuid
import requests

base_url = "http://127.0.0.1:8000/api/"
s = requests.session()
s.auth = ("admin", "admin")

def send(endpoint, data, method="post"):
    data = json.dumps(data)
    resp = s.request(method, base_url + endpoint, data=data, headers={
        "Content-Type": "application/json",
        "Accept": "application/json;indent=4",
        "X-Requested-With": "XMLHttpRequest"  # For `request.is_ajax()`
    })
    if resp.status_code > 300:
        raise Exception(resp.text)
    return resp.json()


def create_product():
    product = send("shoop/product/", {
        "tax_class": 1,
        "sku": str(uuid.uuid4()),
        "type": 1,
        "translations": {
            "en": {
                "name": "Hello"
            }
        }
    })
    return product


def create_shop_product(product):
    product_id = product["id"]

    shop_product = send("shoop/shop_product/", {
        "product": product_id,
        "shop": 1,
    })
    assert not shop_product.get("primary_category")

    shop_product = send("shoop/shop_product/%d/" % shop_product["id"], {
        "primary_category": 1,
        "purchase_multiple": 38
    }, "patch")
    assert shop_product.get("primary_category") == 1
    return shop_product


def create_product_price(product):
    price = send("shoop/simple_product_price/", {
        "product": product["id"],
        "shop": None,
        "group": None,
        "price": 180
    })
    return price


def main():
    product = create_product()
    shop_product = create_shop_product(product)
    price = create_product_price(product)
    print(product["id"])


if __name__ == "__main__":
    main()

Indices and tables