diff --git a/community/py3-django-oscar/0001-Fix-stacked-display-of-categories-without-children-i.patch b/community/py3-django-oscar/0001-Fix-stacked-display-of-categories-without-children-i.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d5a31b36c6363861e0ec79b5b4c85a94c976147c
--- /dev/null
+++ b/community/py3-django-oscar/0001-Fix-stacked-display-of-categories-without-children-i.patch
@@ -0,0 +1,26 @@
+From 27fe44a177b52aaa2299767ac7d879d3c130352d Mon Sep 17 00:00:00 2001
+From: Tuomas Jaakola <tuomas.jaakola@iki.fi>
+Date: Mon, 20 Sep 2021 12:16:20 +0300
+Subject: [PATCH] Fix stacked display of categories without children in
+ catalogue browse template (#3772)
+
+---
+ src/oscar/templates/oscar/catalogue/browse.html | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/oscar/templates/oscar/catalogue/browse.html b/src/oscar/templates/oscar/catalogue/browse.html
+index a3e6b1bd3..e55c8a7af 100644
+--- a/src/oscar/templates/oscar/catalogue/browse.html
++++ b/src/oscar/templates/oscar/catalogue/browse.html
+@@ -25,7 +25,7 @@
+     {% if tree_categories %}
+         <h4>{% trans "Show results for" %}</h4>
+         <div class="side_categories card card-body bg-light">
+-            <ul class="nav nav-list">
++            <ul class="nav nav-list flex-column">
+                 {% for tree_category in tree_categories %}
+                     <li class="mt-2">
+                         <a href="{{ tree_category.url }}">
+-- 
+2.31.1
+
diff --git a/community/py3-django-oscar/0001-SimpleProductSearchHandler-do-not-crash-on-empty-pag.patch b/community/py3-django-oscar/0001-SimpleProductSearchHandler-do-not-crash-on-empty-pag.patch
deleted file mode 100644
index bf42703c8ded0683e33baec415abfad4839ccb2b..0000000000000000000000000000000000000000
--- a/community/py3-django-oscar/0001-SimpleProductSearchHandler-do-not-crash-on-empty-pag.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 992d2df488ea2cf93b550622771f8d952d94465f Mon Sep 17 00:00:00 2001
-From: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
-Date: Mon, 29 Mar 2021 18:27:25 +0300
-Subject: [PATCH] SimpleProductSearchHandler: do not crash on empty page field
-
----
- src/oscar/apps/catalogue/search_handlers.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/oscar/apps/catalogue/search_handlers.py b/src/oscar/apps/catalogue/search_handlers.py
-index ed2b62711..a56529bfe 100644
---- a/src/oscar/apps/catalogue/search_handlers.py
-+++ b/src/oscar/apps/catalogue/search_handlers.py
-@@ -90,7 +90,7 @@ class SimpleProductSearchHandler(MultipleObjectMixin):
- 
-     def __init__(self, request_data, full_path, categories=None):
-         self.categories = categories
--        self.kwargs = {'page': request_data.get('page', 1)}
-+        self.kwargs = {'page': request_data.get('page') or 1}
-         self.object_list = self.get_queryset()
- 
-     def get_queryset(self):
--- 
-2.30.2
-
diff --git a/community/py3-django-oscar/APKBUILD b/community/py3-django-oscar/APKBUILD
index f7177f9c3db2eb7b1731aff0e9fd5c7da670de94..f19ab845bb95f0accfa93b410e034336c241a5aa 100644
--- a/community/py3-django-oscar/APKBUILD
+++ b/community/py3-django-oscar/APKBUILD
@@ -1,8 +1,8 @@
 # Contributor: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
 # Maintainer: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
 pkgname=py3-django-oscar
-pkgver=2.1
-pkgrel=6
+pkgver=3.1
+pkgrel=0
 pkgdesc="Domain-driven e-commerce for Django"
 url="http://oscarcommerce.com/"
 arch="noarch"
@@ -13,9 +13,7 @@ depends="py3-babel py3-django py3-django-extra-views py3-django-haystack
          py3-factory-boy py3-pillow py3-purl"
 makedepends="gettext py3-setuptools"
 source="https://files.pythonhosted.org/packages/source/d/django-oscar/django-oscar-$pkgver.tar.gz
-	0001-SimpleProductSearchHandler-do-not-crash-on-empty-pag.patch
-	django-3.1.patch
-	translation.patch
+	0001-Fix-stacked-display-of-categories-without-children-i.patch
 	"
 builddir="$srcdir/django-oscar-$pkgver"
 
@@ -39,7 +37,7 @@ package() {
 	python3 setup.py install --root "$pkgdir"
 }
 
-sha512sums="b8279eadb637fec4d9979d037fd86c61e16c3a9be518158cc14505200a8b30d1226ac17da6535a724d3f4e71789dab5b7a3583c28c6d6f8480db66a994568ed2  django-oscar-2.1.tar.gz
-bc7ca2cc88d119fe366415531ea09a78df3e242223edea00ede56f77efd7628010fc21237ba7ec6cfc9f7e1ea0c70e8f84ed5363bd6d7ec3b3a68c91da469ea5  0001-SimpleProductSearchHandler-do-not-crash-on-empty-pag.patch
-b08eaf7510d87cd1e7c904b35fcb156ffa5e063da4af93e540b0ba580709fd8dc6b98fb27db4ea8e57711a4f3d404b145524fcb9bf6a23a58886d7b7b071e2f5  django-3.1.patch
-8c49764a5aa44b8c3309f673a3c6f43da1a545cca10e02c8a8868d350b0012c938b9436ab8d20b50e012cfec872af482f7b35d2d5f5ac557f1286224f4704a9e  translation.patch"
+sha512sums="
+513226ab921c28acbd84bdfad4bf51e8647211995f39caaa23895fc02f4cf48c7717b43311e9a2bfc54a53f8f16a462ca1d06702aff2380b65c6f884fa12aa91  django-oscar-3.1.tar.gz
+7c0ce7cdb8f28a95bf88cc07bdd3603a1be140e186b9be8818a1817c13d6259679b594bb64104be65a669d3ad15705122a12d7a7c204e89f740bc7bd4739e416  0001-Fix-stacked-display-of-categories-without-children-i.patch
+"
diff --git a/community/py3-django-oscar/django-3.1.patch b/community/py3-django-oscar/django-3.1.patch
deleted file mode 100644
index 0502c0a8fef0f2aae5bedcac2774248f3dc2d8be..0000000000000000000000000000000000000000
--- a/community/py3-django-oscar/django-3.1.patch
+++ /dev/null
@@ -1,123 +0,0 @@
---- django-oscar-2.1/setup.py
-+++ django-oscar-2.1.dj31/setup.py
-@@ -18,7 +18,7 @@
- from oscar import get_version  # noqa isort:skip
- 
- install_requires = [
--    'django>=2.2,<3.1',
-+    'django>=2.2,<3.2',
-     # PIL is required for image fields, Pillow is the "friendly" PIL fork
-     'pillow>=6.0',
-     # We use the ModelFormSetView from django-extra-views for the basket page
-@@ -37,7 +37,7 @@
-     # Used for oscar.test.newfactories
-     'factory-boy>=2.4.1,<3.0',
-     # Used for automatically building larger HTML tables
--    'django-tables2>=2.2,<2.3',
-+    'django-tables2>=2.3,<2.4',
-     # Used for manipulating form field attributes in templates (eg: add
-     # a css class)
-     'django-widget-tweaks>=1.4.1',
---- django-oscar-2.1/src/oscar/apps/payment/forms.py
-+++ django-oscar-2.1.dj31/src/oscar/apps/payment/forms.py
-@@ -3,6 +3,7 @@
- from datetime import date
- 
- from django import forms
-+from django.core import validators
- from django.core.exceptions import ImproperlyConfigured
- from django.utils.translation import gettext_lazy as _
- 
-@@ -140,10 +141,10 @@
- 
-     def compress(self, data_list):
-         if data_list:
--            if data_list[1] in forms.fields.EMPTY_VALUES:
-+            if data_list[1] in validators.EMPTY_VALUES:
-                 error = self.error_messages['invalid_year']
-                 raise forms.ValidationError(error)
--            if data_list[0] in forms.fields.EMPTY_VALUES:
-+            if data_list[0] in validators.EMPTY_VALUES:
-                 error = self.error_messages['invalid_month']
-                 raise forms.ValidationError(error)
-             year = int(data_list[1])
-@@ -186,10 +187,10 @@
- 
-     def compress(self, data_list):
-         if data_list:
--            if data_list[1] in forms.fields.EMPTY_VALUES:
-+            if data_list[1] in validators.EMPTY_VALUES:
-                 error = self.error_messages['invalid_year']
-                 raise forms.ValidationError(error)
--            if data_list[0] in forms.fields.EMPTY_VALUES:
-+            if data_list[0] in validators.EMPTY_VALUES:
-                 error = self.error_messages['invalid_month']
-                 raise forms.ValidationError(error)
-             year = int(data_list[1])
---- django-oscar-2.1/src/oscar/templates/oscar/dashboard/partials/form_field.html
-+++ django-oscar-2.1.dj31/src/oscar/templates/oscar/dashboard/partials/form_field.html
-@@ -14,7 +14,7 @@
-         <div class="form-group {% if field.errors %}error{% endif %}">
- 
-             {% block label %}
--                {% if not nolabel and field.widget_type != 'CheckboxInput' %}
-+                {% if not nolabel and field.widget_type != 'checkbox' %}
-                     <label for="{{ field.auto_id }}" class="{% if style|default:"stacked" != 'stacked' %}col-sm-4{% endif%} control-label{% if field.field.required %} required{% endif %}">
-                         {{ field.label|safe }}
-                         {% if field.field.required %} <span>*</span>{% endif %}
-@@ -23,14 +23,14 @@
-             {% endblock %}
- 
-             {% block controls %}
--                <div class="{% if style|default:"stacked" != 'stacked' %}col-sm-8{% endif %}{% if field.widget_type == 'CheckboxInput' %} checkbox{% endif %}">
-+                <div class="{% if style|default:"stacked" != 'stacked' %}col-sm-8{% endif %}{% if field.widget_type == 'checkbox' %} checkbox{% endif %}">
-                     {% block widget %}
--                        {% if field.widget_type == 'CheckboxInput' %}
-+                        {% if field.widget_type == 'checkbox' %}
-                             <label for="{{ field.auto_id }}" class="checkbox {% if field.field.required %}required{% endif %}">
-                                 {% render_field field %}
-                                 {{ field.label|safe }}{% if field.field.required %} <span>*</span>{% endif %}
-                             </label>
--                        {% elif field.widget_type == 'RadioSelect' %}
-+                        {% elif field.widget_type == 'radioselect' %}
-                             <label for="{{ field.auto_id }}" class="controls {% if field.field.required %}required{% endif %}">
-                             {% render_field field %}
-                             </label>
---- django-oscar-2.1/src/oscar/templates/oscar/partials/form_field.html
-+++ django-oscar-2.1.dj31/src/oscar/templates/oscar/partials/form_field.html
-@@ -14,7 +14,7 @@
-         <div class="form-group {% if field.errors %}has-error{% endif %}">
- 
-             {% block label %}
--                {% if not nolabel and field.widget_type != 'CheckboxInput' %}
-+                {% if not nolabel and field.widget_type != 'checkbox' %}
-                     <label for="{{ field.auto_id }}" class="{% if style|default:"stacked" != 'stacked' %}col-sm-4{% endif%} control-label{% if field.field.required %} required{% endif %}">
-                         {{ field.label|safe }}
-                     </label>
-@@ -24,7 +24,7 @@
-             {% block controls %}
-                 <div class="{% if style|default:"stacked" != 'stacked' %}col-sm-7{% endif %}">
-                     {% block widget %}
--                        {% if field.widget_type == 'CheckboxInput' %}
-+                        {% if field.widget_type == 'checkbox' %}
-                             <label for="{{ field.auto_id }}" class="checkbox {% if field.field.required %}required{% endif %}">
-                                 {{ field.label|safe }}
-                                 {% render_field field class+="form-control" %}
-Only in django-oscar-2.1.dj31: src/oscar/templates/oscar/partials/form_field.html.orig
---- django-oscar-2.1/src/oscar/templatetags/form_tags.py
-+++ django-oscar-2.1.dj31/src/oscar/templatetags/form_tags.py
-@@ -1,3 +1,5 @@
-+import re
-+
- from django import template
- 
- register = template.Library()
-@@ -24,6 +26,6 @@
- 
-     def render(self, context):
-         field = self.field.resolve(context)
--        if hasattr(field, 'field'):
--            field.widget_type = field.field.widget.__class__.__name__
-+        if not hasattr(field, 'widget_type') and hasattr(field, 'field'):
-+            field.widget_type = re.sub(r'widget$|input$', '', field.field.widget.__class__.__name__.lower())
-         return ''
diff --git a/community/py3-django-oscar/translation.patch b/community/py3-django-oscar/translation.patch
deleted file mode 100644
index 69569a1b162d5729b25400ddd5d85b8ccb660dfc..0000000000000000000000000000000000000000
--- a/community/py3-django-oscar/translation.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- django-oscar-2.1/src/oscar/locale/fi/LC_MESSAGES/django.po
-+++ django-oscar-2.1.trans/src/oscar/locale/fi/LC_MESSAGES/django.po
-@@ -5342,7 +5342,7 @@
- 
- #: templates/oscar/basket/partials/basket_content.html:29
- msgid "Items to buy now"
--msgstr "Nyt ostettavat tuoteet"
-+msgstr "Nyt ostettavat tuotteet"
- 
- #: templates/oscar/basket/partials/basket_content.html:31
- #: templates/oscar/basket/partials/basket_content.html:180
-@@ -5651,7 +5651,7 @@
- 
- #: templates/oscar/catalogue/detail.html:87
- msgid "Variants:"
--msgstr ""
-+msgstr "Muunnokset:"
- 
- #: templates/oscar/catalogue/detail.html:104
- msgid "Product Description"