Table Of Contents

Previous topic

Satchmo Views

Next topic

Google Base

Documentation Version:

Signals in Satchmo

Signals are a very powerful tool available in Django that allows you to decouple aspects of your application. The Django Signals Documentation, has this summary:

“In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.”

In addition to all of the built in Django signals, Satchmo includes a number of store related signals. By using these signals, you can add very unique customizations to your store without needing to modify the Satchmo code.

Signal Descriptions

livesettings.signals

configuration_value_changed

Sent after a value from the configuration application has been changed.

Arguments sent with this signal:

sender
The instance of livesettings.values.Value that was changed
old_value
The old value of the setting
new_value
The new value of the settings
setting
The instance of livesettings.values.Value that was changed (Note: this argument is the same as sender)

satchmo_store.shop.signals

order_success

Sent when an order is complete and the balance goes to zero during a save.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Order that was successful
order
The instance of satchmo_store.shop.models.Order that was successful (Note: this argument is the same as sender)

order_cancel_query

Sent when an order is about to be cancelled and asks listeners if they allow to do so.

By default, orders in states ‘Shipped’, ‘Completed’ and ‘Cancelled’ are not allowed to be cancelled. The default verdict is stored in order.is_cancellable flag. Listeners can modify this flag, according to their needs.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Order that is about to be canceleld
order
The instance of satchmo_store.shop.models.Order that is about to be cencelled (Note: this argument is the same as sender)

order_cancelled

Sent when an order has been cancelled (it’s status already reflects it and has been saved to the database).

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Order that was cancelled
order
The instance of satchmo_store.shop.models.Order that was cancelled (Note: this argument is the same as sender)

satchmo_cart_add_complete

Sent after an item has been successfully added to the cart.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Cart that was added to
cart
The instance of satchmo_store.shop.models.Cart that was added to (Note: this argument is the same as sender)
added_item
The instance of satchmo_store.shop.models.CartItem that was added (or updated) to the cart
product
The instance of product.models.Product that was added to the cart
request
The HttpRequest object used in the view to add the item to the cart
form
The POST data for the form used to add the item to the cart

satchmo_cart_add_verify

Sent before an item is added to the cart.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Cart that is having an item added to it
cart
The instance of satchmo_store.shop.models.Cart that is having an item added to it (Note: this argument is the same as sender)
cartitem
An instance of satchmo_store.shop.models.CartItem that is being added to the cart
added_quantity
The number of cartitem items being added to the cart
details

A list of dictionaries containing additonal details about the item if the item is a custom product or a gift certificate product. Each dictionaries will contain the following information:

name
The name of the detail
value
The value of the detail
sort_order
The order the detail should be listed in displays
price_change
The price change of the detail, default of zero

satchmo_cart_changed

Sent whenever the status of the cart has changed. For example, when an item is added, removed, or had it’s quantity updated.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Cart that was changed
cart
The instance of satchmo_store.shop.models.Cart that was changed (Note: this argument is the same as sender)
request
The HttpRequest object used in the view to change the cart

satchmo_cartitem_price_query

Sent by the pricing system to allow price overrides when displaying line item prices.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.CartItem being querried for price overrides.
cartitem
The instance of satchmo_store.shop.models.CartItem being querried for price overrides (Note: this argument is the same as sender)

satchmo_cart_details_query

Sent before an item is added to the cart so that listeners can update product details.

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Cart being added to
product
Either an instance of product.models.Product or product.models.ConfigurableProduct being added to the cart
quantity
The number of items (represented as a Decimal) being added to the cart
details

A list of dictionaries containing additonal details about the item if the item is a custom product or a gift certificate product. Each dictionaries will contain the following information:

name
The name of the detail
value
The value of the detail
sort_order
The order the detail should be listed in displays
price_change
The price change of the detail, default of zero
request
The HttpRequest object used in the view to add an item to the cart
form
The POST data for the form used to add the item to the cart

satchmo_post_copy_item_to_order

Sent after each item from the cart is copied into an order

Arguments sent with this signal:

sender
The instance of satchmo_store.shop.models.Cart being copied
cartitem
The instance of satchmo_store.shop.models.CartItem being copied into an order
order
The instance of satchmo_store.shop.models.Order having items copied into it
orderitem
The instance of satchmo_store.shop.models.OrderItem being added to the order

satchmo_context

Sent after the satchmo_store.shop.context_processors.settings has been run, but before the context is returned. This signal can be used to modify the context returned by the context processor.

Arguments sent with this signal:

sender
The satchmo_store.shop.models.Config instance for the current store configuration
context

A dictionary containing the context to be returned by the context processor. The dictionary contains:

shop_base
The base URL for the store
shop
An instance of satchmo_store.shop.models.Config representing the current store configuration
shop_name
The shop name
media_url
The current media url, taking into account SSL
cart_count
The number of items in the cart
cart
An instance of satchmo_store.shop.models.Cart representing the current cart
categories
A QuerySet of all the product.models.Category objects for the current site.
is_secure
A boolean representing weather or not SSL is enabled
request
The HttpRequest object passed into the context processor
login_url
The login url defined in settings.LOGIN_URL
logout_url
The logout url defined in settings.LOGOUT_URL
sale
An instance of product.models.Discount if there is a current sale, or None

cart_add_view

Sent by satchmo_store.shop.views.smart.smart_add to allow listeners to optionally change the responding function

Arguments sent with this signal:

sender
The satchmo_store.shop.models.Cart model (Note: this is not an instance)
request
The HttpRequest object used by the view
method

A dictionary containing a single key view to be updated with the function to be called by smart_add. For example:

method = {'view': cart.add }

satchmo_store.contact.signals

satchmo_contact_view

Sent when contact information is viewed or updated before a template is rendered. Allows you to override the contact information and context passed to the templates used.

Arguments sent with this signal:

sender
An instance of satchmo_store.contact.models.Contact representing the contact information being viewed, or None if the information cannot be found.
contact
An instance of satchmo_store.contact.models.Contact representing the contact information being viewed, or None if the information cannot be found (Note: This argument is the same as sender).
contact_dict
A dictionary containing the intitial data for the instance of satchmo_store.contact.forms.ExtendedContactInfoForm instance that will be rendered to the user.

satchmo_contact_location_changed

Sent after a user changes their location in their profile

Arguments sent with this signal:

sender
The instance of satchmo_store.contact.forms.ContactInfoForm which was responsible for the location change.
contact
The instance of satchmo_store.contact.models.Contact which was updated with a new location.

form_init

Sent when a contact info form is initialized. Contact info forms include:

  • contact.forms.ContactInfoForm
  • contact.forms.ExtendedContactInfoForm
  • payment.forms.PaymentContactInfoForm

Arguments sent with this signal:

sender
The model of the form being initialized. The value of sender will be one of the models defined above.
form
An instance of the form (whose type is defined by sender) being intitialized.

form_save

Sent after a form has been saved to the database

Arguments sent with this signal:

sender

The form model of the form being set (Note: Not an instance). Possible values include:

  • satchmo_store.contact.forms.ContactInfoForm
  • payment.modules.purchaseorder.forms.PurchaseorderPayShipForm
  • payment.forms.CreditPayShipForm
  • payment.forms.SimplePayShipForm
  • payment.forms.PaymentContactInfoForm
form
  • The instance of the form defined by one of the above models that was saved.

validate_postcode

Sent when a form that contains postal codes (shipping and billing forms) needs to validate. This signal can be used to custom validate postal postal codes. Any listener should return the validated postal code or raise an exception for an invalid postal code.

Arguments sent with this signal:

sender
An instance of satchmo_store.contact.forms.ContactInfoForm which is validating it’s postal codes.
postcode
The postal code as a string being validated
country
An instance of l10n.models.Country that was selected in the form (or specified in the configuration if local sales are only allowed)

satchmo_store.accounts.signals

satchmo_registration

Sent after a user has registered an account with the store.

Arguments sent with this signal:

sender
The instance of satchmo_store.accounts.forms.RegistrationForm which was submitted.
contact
The instance of satchmo_store.contact.models.Contact that was saved to the database
subscribed
A boolean reflecting weather or not the user subscribed to a newsletter (defaults to False)
data
The cleaned_data dictionary of the submitted form

satchmo_registration_verified

Sent after a user account has been verified. This signal is also sent right after an account is created if account verification is disabled.

Arguments sent with this signal:

sender
An instance of satchmo_store.models.Contact if the account was verified via email (Note: this is the same argument as contact), or an instance of satchmo_store.accounts.forms.RegistrationForm if account verification is disabled.
contact
The instance of satchmo_store.models.Contact that was registered

satchmo_ext.newsletter.signals

newsletter_subscription_updated

Sent after a newsletter subscription has been updated

Arguments sent with this signal:

sender
An instance of satchmo_store.models.Contact representing the person having the subscription status updated
old_state
Boolean representing the old state of subscription
new_state
Boolean representing the new state of the subscription
contact
An instance of satchmo_store.models.Contact representing the person having the subscription status update (Note: this argument is the same as sender)
attributes
An empty dictionary. This argument is not currently used.

payment.signals

confirm_sanity_check

Sent after ensuring that the cart and order are valid

Arguments sent with this signal:

sender
An instance of payment.views.confirm.ConfirmController which performed the sanity check.
controller
An instance of payment.views.confirm.ConfirmController which perofmred the sanity check (Note: this is the same argument as sender)

payment_form_init

Sent when a payment form is initialized. Payment forms include:

  • payment.forms.PaymentContactInfoForm
  • payment.forms.SimplePayShipForm

Arguments sent with this signal:

sender
The model of the form being initialized. The value of sender will be one of the models defined above.
form
An instance of the form (whose type is defined by sender) being intitialized.
Example Usage

This signal can be combined with the payment.listeners.form_terms_listener to add a custom terms and conditions acceptance box into your checkout flow.

First, add the terms view in your /localsite/urls.py file:

urlpatterns += patterns('',
url(r'^shop_terms/$', 'project-name.localsite.views.shop_terms',
    name="shop_terms"),
)

Next, create the view in your /localsite/views.py to display the terms:

from django.shortcuts import render_to_response
from django.template import RequestContext

def shop_terms(request):
    ctx = RequestContext(request, {})
    return render_to_response('localsite/shop-terms.html',
        context_instance=ctx)

Now, you will need modify the checkout html to display the new form. Copy /satchmo/apps/payment/templates/shop/checkout/pay_ship.html to /project-name/templates/shop/checkout/pay_ship.html.

Add the following code to the copied pay_ship.html to display the form:

{{ form.terms }} {{ form.terms.label|safe }}
{% if form.terms.errors %}<br/>**{{ form.terms.errors|join:", " }}{% endif %}

Make sure you register the forms_terms_listener by adding the following code to your /localsite/models.py:

from payment.forms import SimplePayShipForm
from payment.listeners import form_terms_listener
from signals_ahoy.signals import form_init

form_init.connect(form_terms_listener, sender=SimplePayShipForm)

The final step is to create your actual /templates/shop-terms.html, like this:

{% extends "base.html" %}
{% block content %}
<p>Put all of your sample terms here.</p>
{% endblock %}

Now, when users checkout, they must agree to your store’s terms.

payment_methods_query

Sent when a payment.forms.PaymentMethodForm is initialized. Receivers have cart/order passed in variables to check the contents and modify methods list if neccessary.

Arguments sent with this signal:

sender
The model payment.forms.PaymentMethodForm
methods
A list of 2-element tuples containing the currently active payment methods. Each tuple contains the payment module name as well as the label for that payment module
cart
An instance of satchmo_store.shop.models.Cart representing the current cart
order
An instance of satchmo_store.shop.models.Order representing the current order
contact
An instance of satchmo_store.contact.models.Contact representing the current customer (if authenticated, so it may be None).

payment_form_validation

Sent at the end of clean() method of:

  • payment.forms.PaymentMethodForm
  • payment.forms.PaymentContactInfoForm

Arguments sent with this signal:

sender
  • The model of the form that is finishing validation
form
  • The instance of the form whose type is that of sender

form_save

Sent after one of the following forms (or their subtypes) has been saved:

  • payment.forms.PaymentContactInfoForm
  • payment.forms.SimplePayShipForm
  • payment.forms.CreditPayShipForm
  • payment.modules.purchaseorder.forms.PurcahseorderPayShipForm
  • satchmo_store.contact.forms.ContactInfoForm

Arguments sent with this signal:

sender
  • The model of the form that was just saved
object
  • A satchmo_store.contact.models.Contact instance if the form being saved is an instance of satchmo_store.contact.forms.ContactInfoForm otherwise this value does not exist.
formdata
  • The data associated with the form if the form being saved is an instance of satchmo_store.contact.forms.ContactInfoForm otherwise this value does not exist.
form
  • The instance of the form whose type is that of sender

payment_choices

Sent after a list of payment choices is compiled, allows the editing of payment choices.

Arguments sent with this signal:

sender

Always None
choices
A list of 2-element tuples containing the currently active payment methods. Each tuple contains the payment module name as well as the label for that payment module

product.signals

index_prerender

Sent before an index is rendered for categories or brands

Arguments sent with this signal:

sender

One of the following models:

  • product.models.product
  • satchmo_ext.brand.models.Brand
  • ‘’satchmo_ext.brand.models.BrandProduct``
request
The HttpRequest object used by the view
context
A dictionary containing the context that will be used to render the template. The contents of this dictionary changes depending on the sender.
category
An instance of product.models.Category representing the category being viewed. This paramemter will not exist for brand listings.
brand
An instance of satchmo_ext.brand.modes.Brand representing the brand being viewed. This parameter will not existi for category listings.
object_list
A QuerySet of product.models.Product objects

satchmo_price_query

Sent before returning the price of a product. The following models send this signal:

  • product.models.ProductPriceLookup
  • product.models.Price
  • satchmo_ext.tieredpricing.models.TieredPrice

Arguments sent with this signal:

sender
The instance of the model sending the price query
price
The instance of the model sending the price query (Note: This argument is the same as sender)
slug
The slug of the product being querried (Note: Only sent with product.models.ProductPriceLookup)
discountable
A boolean representing weather or not the product price is discountable (Note: only sent with product.models.ProductPriceLookup)

subtype_order_success

Sent when a downloadable product is successful

Arguments sent with this signal:

sender
The instance of product.models.DownloadableProduct that was successfully ordered.
product
The instance of product.models.DownoadableProduct that was successfully ordered.
order
The instance of satchmo_store.shop.models.Order that was sucessful
subtype
always the string “download”

discount_filter_items

Sent to verify the set of order items that are subject to discount.

Arguments sent with this signal:

sender
The instance of product.models.Discount that is being applied.
discounted
A dictionary, where the keys are IDs of items which are subject to discount by standard criteria.
order
The instance of satchmo_store.shop.models.Order being processed.

satchmo_utils.signals

collect_urls

Sent by urls modules to allow listeners to add or replace urls to that module

Arguments sent with this signal:

sender
The module having url patterns added to it
patterns
The url patterns to be added. This is an instance of django.conf.urls.defaults.patterns
section
The name of the section adding the urls (Note: this argument is not always provided). For example ‘__init__’ or ‘product’

Example Usage

Usage:

from satchmo_store.shop.signals import satchmo_cart_add_complete
import myviews

satchmo_cart_add_complete.connect(myviews.cart_add_listener, sender=None)

Example - Putting it All Together

This section contains a brief example of how to use signals in your application. For this example, we want to have certain products that are only available to members. Everyone can see the products, but only members can add to the cart. If a non-member tries to purchase a product, they will get a clear error message letting them know they need to be a member.

The first thing to do is create a listeners.py file in your app. In this case, the file would look something like this:

"""
A custom listener that will evaluate whether or not the product being added
to the cart is available to the current user based on their membership.
"""
from satchmo_store.shop.exceptions import CartAddProhibited
from django.utils.translation import gettext_lazy as _

class ContactCannotOrder(CartAddProhibited):
    def __init__(self, contact, product, msg):
        super(ContactCannotOrder, self).__init__(product, msg)
        self.contact = contact

def veto_for_non_members(sender, cartitem=None, added_quantity=0, **kwargs):
    from utils import can_user_buy
    customer = kwargs['cart'].customer
    if can_user_buy(cartitem.product, customer):
        return True
    else:
        msg = _("Only members are allowed to purchase this product.")
        raise ContactCannotOrder(customer, cartitem.product, msg)

Next, you need to create the can_user_buy function. Your utils.py file could look something like this (details left up to the reader):

def can_user_buy(product, contact=None):
    """
    Given a product and a user, return True if that person can buy it and
    False if they can not.
    This doesn't work as it stands now. You'll need to customize the
    is_member function
    """
    if is_member(contact):
        return True
    else:
        return False

The final step is to make sure your new listener is hooked up. In your models.py add the following code:

from listeners import veto_for_non_members
from satchmo_store.shop import signals

signals.satchmo_cart_add_verify.connect(veto_for_non_members, sender=None)

Now, you should be able to restrict certain products to only your members. The nice thing is that you’ve done this without modifying your satchmo base code.