Oscar 2.1 release notes



Welcome to Oscar 2.1! This is a significant release which includes a number of new features and performance improvements.


Oscar 2.1 is compatible with Django versions 2.2 and 3.0, and Python versions 3.5, 3.6, 3.7 and 3.8.

Support for Django versions 1.11 and 2.0 has been dropped.

What’s new in Oscar 2.1?

  • The ability to add arbitrary surcharges to orders (e.g., a processing fee for a particular payment method) was introduced. See How to configure surcharges for details on how to configure this. This change requires a database migration.

  • The database performance of offer.Range.all_products() was substantially improved. The internals of that method have changed and specifically Range.invalidate_cached_ids() has been removed and replaced with Range.invalidate_cached_queryset().

  • The upload_to argument of image fields in Oscar’s ProductImage and ProductAttributeValue models was changed to use a callable, so that Django doesn’t generate migrations if a project modifies the OSCAR_IMAGE_FOLDER to specify a custom directory structure for uploaded images. This change requires a database migration.

  • catalogue.Category now has an is_public boolean field that serves a similar purpose to catalogue.Product.is_public - i.e., to hide categories public views. The Category model also now has a custom manager that provides a browsable() queryset method that excludes non-public categories. This change requires a database migration.

    Category hierarchy implies that the children of any non-public category are also non-public. This is enforced through an ancestors_are_public field on the Category model.

  • A date_updated field was added to the basket.Line model, which is updated every time a line is saved. This change requires a database migration.

Communications app

A new communication app was introduced to provide a single point of entry for all communications sent by Oscar. This is a significant change with implications as follows:

  • Projects will need to add oscar.apps.communication.apps.CommunicationConfig to INSTALLED_APPS.

    The CommunicationEventType, Email and Notification models have moved from the customer app to the communication app. In order to preserve existing data, the table names for these models are unchanged.

    This change requires a database migration.

  • The Dispatcher class moved from customer.utils to communication.utils. Dispatcher is now responsible for sending all notifications, and not just emails.

  • A CustomerDispatcher utility class that wraps the core Dispatcher has been introduced to the customer app for sending communications to customers.

  • An AlertsDispatcher utility class that wraps the core Dispatcher has been introduced to the customer.alerts module for sending product alerts.

  • An OrderDispatcher utility class that wraps the core Dispatcher has been introduced to the order app for sending order related communications.

  • A new setting, OSCAR_SAVE_SENT_EMAILS_TO_DB controls whether emails sent through the Dispatcher are saved to the database. This defaults to True.

  • The ability to send multipart emails with attachments was added to the new dispatcher.

  • All communication email templates (commtype_*) have moved from moved from customer/emails to communication/emails.

  • Templates in customer/email/ and customer/notification/ have moved to communication/email/ and communication/notification/.

  • An absolute_url template tag was introduced to facilitate generating absolute URLs in templates for a given domain and path. The schema for generated URLs is configured via the OSCAR_URL_SCHEMA setting, which defaults to http.

Backwards incompatible changes in Oscar 2.1

  • The category field has been removed from the communication.Notification model. This change requires database migration.

  • The checkout.mixins.OrderPlacementMixin.send_confirmation_message method has been replaced with a new send_order_placed_email method.

  • customer.notifications.context_processors.notifications has moved to communication.notifications.context_processors.notifications.

Bug fixes

  • Fixed a bug in the handling of requests to save an item in the basket for later(#3215).

  • Fixed an error when deleting an offer whose related conditions/benefits have been deleted.

  • Fixed handling of count conditions in MultibuyDiscountBenefit. Previously, when a count condition was used with this benefit it would result in a discount being applied for all items in the basket rather than the cheapest one.

  • Fixed a bug where a line could not be deleted from the basket, if the basket had another line with a validation error - i.e. its product was out of stock (see #2791 and #1654).

  • Fixed a bug where non-public child products were not excluded from parent product forms and detail views.

Removal of deprecated features

  • Support for verifying order hashes using an insecure MD5 algorithm generated by Oscar 1.5 and below has been dropped. The OSCAR_DEPRECATED_ORDER_VERIFY_KEY setting is no longer used. Order verification hashes generated by Oscar 1.5 and lower will no longer validate.

  • offer.Range.contains() has been removed. Use contains_product() instead.

  • catalogue.managers.ProductManager has been removed. Use catalogue.managers.ProductQuerySet.as_manager() instead.

  • catalogue.managers.BrowsableProductManager has been removed. Use Product.objects.browsable() instead.

  • catalogue.Product.browsable has been removed. Use Product.objects.browsable() instead.

  • Invalid URLs supplied to OSCAR_DASHBOARD_NAVIGATION are no longer ignored. URLs that cannot be resolved will now result in a NoReverseMatch exception. URLs that are not provided by a subclass of oscar.core.application.OscarDashboardConfig will result in a KeyError.

  • customer.forms.PasswordResetForm.get_reset_url has been removed.

  • The internal and undocumented class oscar.core.compat.UnicodeCSVReader has been removed. Use csv.reader instead.

Minor changes

  • OrderPlacementMixin.place_order now ignores inactive vouchers when placing an order (instead of raising an exception), for consistency with how the basket flows handle inactive vouchers.

  • Fixed the logic of StockRequired.parent_availability_policy to use child products to determine availability of children, rather than the parent.

  • customer.forms.PasswordResetForm now uses the parent class’ get_users() method to determine the list of users to send an email to. get_users() filters out users who do not currently have a usable password - which did not happen previously.

    This change was made in response to changes in Django to address CVE-2019-19844. Oscar’s PasswordResetForm was not vulnerable to the issue in Django’s form, but it was possible to send a password reset email to unintended recipients because of unicode character collision.

  • catalogue.Product.is_public is now an indexed field. This change requires a database migration.

  • When a voucher that was created through the Oscar dashboard is deleted, the auto-generated offer that was created with the voucher is also deleted.

  • Fixed the brand_title block in partials/brand.html so that it doesn’t span unclosed HTML tags.

  • customer.views.ProfileUpdateView.form_valid was modified to use a new send_email_changed_email method.

  • customer.views.ChangePasswordView.form_valid was modified to use a new send_password_changed_email method.

  • A public method was added to the ProductQuerySet, which filters on products with is_public=True.

Dependency changes

Python package dependencies:

  • Upgraded pillow to version 6.0.0 or higher.

  • Upgraded django-extra-views to version 0.13.

  • Upgraded django-haystack to version 3.0 or higher.

  • Upgraded django-phonenumber-field to version 3.0.

  • Upgraded django-tables2 to version 2.2.

  • Upgraded sorl-thumbnail (optional requirement) to version 12.6.

  • Upgraded easy-thumbnails (optional requirement) to version 2.7.

Javascript dependencies:

  • Upgraded jquery to version 3.5.

  • Upgraded inputmask to version 5.0.

  • Upgraded select2 to version 4.0.

  • Upgraded tinymce to version 5.3.

Deprecated features

  • customer.alerts.utils.send_alerts is deprecated. Use AlertsDispatcher.send_alerts instead.

  • customer.alerts.utils.send_alert_confirmation is deprecated. Use AlertsDispatcher.send_product_alert_confirmation_email_for_user instead.

  • customer.alerts.utils.send_product_alerts is deprecated. Use AlertsDispatcher.send_product_alert_email_for_user instead.

  • customer.notifications.services.notify_user is deprecated. Use Dispatcher.notify_user``.

  • customer.notifications.services.notify_users is deprecated. Use Dispatcher.notify_users instead.