Merge branch 'release/1.1.0'
This commit is contained in:
commit
b24b65da5c
60
src/functional_tests/test_address.py
Normal file
60
src/functional_tests/test_address.py
Normal file
@ -0,0 +1,60 @@
|
||||
import os, time
|
||||
from selenium.webdriver.firefox.webdriver import WebDriver
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.support.ui import Select
|
||||
from selenium.common.exceptions import WebDriverException
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
||||
|
||||
class AddressTests(StaticLiveServerTestCase):
|
||||
fixtures = ['products.json']
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.browser = WebDriver()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.browser.quit()
|
||||
super().tearDownClass()
|
||||
|
||||
def test_invalid_address_returns_errorlist(self):
|
||||
self.browser.get(self.live_server_url + '/checkout/address/')
|
||||
self.assertEqual(
|
||||
self.browser.title,
|
||||
'Checkout | Port Townsend Roasting Co.'
|
||||
)
|
||||
|
||||
full_name_input = self.browser.find_element_by_name("full_name")
|
||||
full_name_input.send_keys('John Doe')
|
||||
email_input = self.browser.find_element_by_id('id_email')
|
||||
email_input.send_keys('john@example.com')
|
||||
street_address_1_input = self.browser.find_element_by_name('street_address_1')
|
||||
street_address_1_input.send_keys('1579')
|
||||
city_input = self.browser.find_element_by_name('city')
|
||||
city_input.send_keys('Logan')
|
||||
state_select = select = Select(self.browser.find_element_by_name('state'))
|
||||
state_select.select_by_value('UT')
|
||||
postal_code_input = self.browser.find_element_by_name('postal_code')
|
||||
postal_code_input.send_keys('37461')
|
||||
self.browser.find_element_by_xpath('//input[@value="Continue to Payment"]').click()
|
||||
# try:
|
||||
# WebDriverWait(self.browser, 4).until(
|
||||
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
|
||||
# )
|
||||
# finally:
|
||||
# self.browser.quit()
|
||||
|
||||
self.assertEqual(
|
||||
self.browser.find_element_by_css_selector(
|
||||
'.errorlist li'
|
||||
).text,
|
||||
'USPS: Address Not Found.'
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -190,57 +190,40 @@ TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django.TemplateBacke
|
||||
SITE_ID = 1
|
||||
|
||||
# Logging
|
||||
if DEBUG:
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
||||
'style': '{',
|
||||
}
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'filters': {
|
||||
'require_debug_false': {
|
||||
'()': 'django.utils.log.RequireDebugFalse',
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'require_debug_true': {
|
||||
'()': 'django.utils.log.RequireDebugTrue',
|
||||
},
|
||||
'root': {
|
||||
'handlers': ['console'],
|
||||
},
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
||||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
'filters': ['require_debug_false'],
|
||||
'filename': '/var/log/django-ptcoffee/debug.log',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
}
|
||||
else:
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
||||
'style': '{',
|
||||
},
|
||||
'simple': {
|
||||
'format': '{levelname} {message}',
|
||||
'style': '{',
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'django.file': {
|
||||
'handlers': ['file'],
|
||||
'level': 'INFO',
|
||||
'propagate': True,
|
||||
},
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': '/var/log/django-ptcoffee/debug.log',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'django': {
|
||||
'handlers': ['file'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
CART_SESSION_ID = 'cart'
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ input[type=submit],
|
||||
color: var(--fg-color);
|
||||
background-color: var(--yellow-color);
|
||||
|
||||
padding: 0.25rem 1rem;
|
||||
padding: 0.4rem 1rem;
|
||||
border-radius: 0.2rem;
|
||||
border: none;
|
||||
|
||||
@ -206,6 +206,15 @@ input[type=submit]:hover,
|
||||
background-color: var(--yellow-alt-color);
|
||||
}
|
||||
|
||||
.errorlist {
|
||||
background-color: var(--red-color);
|
||||
color: white;
|
||||
list-style: none;
|
||||
padding: 0 1rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* Contact form
|
||||
========================================================================== */
|
||||
@ -788,11 +797,33 @@ article + article {
|
||||
|
||||
/* Checkout / Shipping Address
|
||||
========================================================================== */
|
||||
.checkout__address-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 0 2rem;
|
||||
}
|
||||
|
||||
|
||||
.checkout__address-form .errorlist {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.checkout__address-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.checkout__address-form .errorlist {
|
||||
grid-column: 1;
|
||||
}
|
||||
}
|
||||
.checkout__address-form p:last-child {
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
.checkout__address-form input,
|
||||
.checkout__address-form select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 24rem;
|
||||
}
|
||||
|
||||
.checkout__address {
|
||||
|
||||
@ -121,7 +121,14 @@ class Cart:
|
||||
except TypeError as e:
|
||||
return Decimal('0.00')
|
||||
usps = USPSApiWithRate(settings.USPS_USER_ID, test=True)
|
||||
validation = usps.get_rate(usps_rate_request)
|
||||
|
||||
try:
|
||||
validation = usps.get_rate(usps_rate_request)
|
||||
except ConnectionError:
|
||||
raise ValidationError(
|
||||
'Could not connect to USPS, try again.'
|
||||
)
|
||||
|
||||
logger.info(validation.result)
|
||||
if not 'Error' in validation.result['RateV4Response']['Package']:
|
||||
rate = validation.result['RateV4Response']['Package']['Postage']['CommercialRate']
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import logging
|
||||
import logging, json
|
||||
from requests import ConnectionError
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.mail import EmailMessage
|
||||
from django.core.exceptions import ValidationError
|
||||
from usps import USPSApi, Address
|
||||
|
||||
from core.models import Order
|
||||
from core import CoffeeGrind
|
||||
@ -35,8 +39,7 @@ class AddToSubscriptionForm(forms.Form):
|
||||
|
||||
|
||||
class AddressForm(forms.Form):
|
||||
first_name = forms.CharField()
|
||||
last_name = forms.CharField()
|
||||
full_name = forms.CharField()
|
||||
email = forms.EmailField()
|
||||
street_address_1 = forms.CharField()
|
||||
street_address_2 = forms.CharField(required=False)
|
||||
@ -46,6 +49,54 @@ class AddressForm(forms.Form):
|
||||
)
|
||||
postal_code = forms.CharField()
|
||||
|
||||
def process_full_name(self, full_name):
|
||||
name = full_name.split()
|
||||
|
||||
if len(name) > 2:
|
||||
last_name = ''.join(name.pop(-1))
|
||||
first_name = ' '.join(name)
|
||||
elif len(name) > 1:
|
||||
first_name = name[0]
|
||||
last_name = name[1]
|
||||
else:
|
||||
first_name = name[0]
|
||||
last_name = ''
|
||||
|
||||
return first_name, last_name
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
address = Address(
|
||||
name=cleaned_data.get('full_name'),
|
||||
address_1=cleaned_data.get('street_address_1'),
|
||||
address_2=cleaned_data.get('street_address_2'),
|
||||
city=cleaned_data.get('city'),
|
||||
state=cleaned_data.get('state'),
|
||||
zipcode=cleaned_data.get('postal_code')
|
||||
)
|
||||
usps = USPSApi(settings.USPS_USER_ID, test=True)
|
||||
|
||||
try:
|
||||
validation = usps.validate_address(address)
|
||||
except ConnectionError:
|
||||
raise ValidationError(
|
||||
'Could not connect to USPS, try again.'
|
||||
)
|
||||
|
||||
|
||||
if 'Error' in validation.result['AddressValidateResponse']['Address']:
|
||||
error = validation.result['AddressValidateResponse']['Address']['Error']['Description']
|
||||
raise ValidationError(
|
||||
"USPS: " + error
|
||||
)
|
||||
|
||||
try:
|
||||
cleaned_data['postal_code'] = validation.result['AddressValidateResponse']['Address']['Zip5']
|
||||
except KeyError:
|
||||
raise ValidationError(
|
||||
'Could not find Zip5'
|
||||
)
|
||||
|
||||
class OrderCreateForm(forms.ModelForm):
|
||||
email = forms.CharField(widget=forms.HiddenInput())
|
||||
first_name = forms.CharField(widget=forms.HiddenInput())
|
||||
|
||||
19
src/storefront/templates/storefront/address_create_form.html
Normal file
19
src/storefront/templates/storefront/address_create_form.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<article>
|
||||
<header>
|
||||
<p><a href="{% url 'storefront:customer-detail' user.pk %}">← Back</a></p>
|
||||
<h1>Create Address</h1>
|
||||
</header>
|
||||
<section>
|
||||
<form method="post" action="{% url 'storefront:customer-address-create' customer.pk %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<p>
|
||||
<input type="submit" value="Create address">
|
||||
</p>
|
||||
</form>
|
||||
</section>
|
||||
</article>
|
||||
{% endblock %}
|
||||
@ -17,6 +17,7 @@
|
||||
<input type="submit" value="Continue to Payment">
|
||||
</p>
|
||||
</form>
|
||||
<p>We validate addresses with USPS, if you are having issues please contact us at <a href="mailto:support@ptcoffee.com">support@ptcoffee.com</a> or use the contact information found on our <a href="{% url 'storefront:contact' %}">contact</a> page.</p>
|
||||
</section>
|
||||
</article>
|
||||
{% endblock %}
|
||||
|
||||
@ -30,8 +30,13 @@
|
||||
</address>
|
||||
{% endwith %}
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h4>Your addresses</h4>
|
||||
<p>
|
||||
<a href="{% url 'storefront:customer-address-create' user.pk %}" class="action-button">+ New address</a>
|
||||
</p>
|
||||
<div>
|
||||
<p><strong>All addresses</strong></p>
|
||||
{% for address in customer.addresses.all %}
|
||||
<p>
|
||||
<address>
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
</header>
|
||||
<section class="checkout__address">
|
||||
<h3>Shipping address</h3>
|
||||
<p>{{shipping_address.email}}</p>
|
||||
<address>
|
||||
{{shipping_address.first_name}}
|
||||
{{shipping_address.last_name}}<br>
|
||||
|
||||
106
src/storefront/tests/test_forms.py
Normal file
106
src/storefront/tests/test_forms.py
Normal file
@ -0,0 +1,106 @@
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
|
||||
from measurement.measures import Weight
|
||||
from django.test import TestCase, Client, RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
|
||||
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
|
||||
|
||||
from accounts.models import User, Address
|
||||
from core.models import Product, Order
|
||||
from core import CoffeeGrind
|
||||
from storefront.views import OrderCreateView
|
||||
from storefront.forms import AddressForm
|
||||
from storefront.cart import Cart
|
||||
from storefront.payments import CreateOrder
|
||||
|
||||
from . import RequestFaker
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class AddressFormTest(TestCase):
|
||||
|
||||
def test_invalid_address_returns_form_error(self):
|
||||
form = AddressForm(data={
|
||||
'full_name': 'John Doe',
|
||||
'email': 'john@example.com',
|
||||
# Wrong street address
|
||||
'street_address_1': '1579 ',
|
||||
'street_address_2': '',
|
||||
'city': 'Logan',
|
||||
'state': 'UT',
|
||||
# Wrong Zip code
|
||||
'postal_code': '23481'
|
||||
})
|
||||
self.assertFalse(form.is_valid())
|
||||
|
||||
def test_usps_finds_zip_from_address(self):
|
||||
form = AddressForm(data={
|
||||
'full_name': 'John Doe',
|
||||
'email': 'john@example.com',
|
||||
'street_address_1': '1579 Talon Dr.',
|
||||
'street_address_2': '',
|
||||
'city': 'Logan',
|
||||
'state': 'UT',
|
||||
# Wrong Zip code
|
||||
'postal_code': '23481'
|
||||
})
|
||||
self.assertTrue(form.is_valid())
|
||||
if form.is_valid():
|
||||
cleaned_data = form.cleaned_data
|
||||
postal_code = cleaned_data.get('postal_code')
|
||||
self.assertEqual(postal_code, '84321')
|
||||
|
||||
|
||||
def test_invalid_address_returns_form_error(self):
|
||||
form = AddressForm(data={
|
||||
'full_name': 'John Doe',
|
||||
'email': 'john@example.com',
|
||||
# Wrong street address
|
||||
'street_address_1': '1579',
|
||||
'street_address_2': '',
|
||||
'city': 'Logan',
|
||||
'state': 'UT',
|
||||
# Wrong Zip code
|
||||
'postal_code': '84321'
|
||||
})
|
||||
self.assertFalse(form.is_valid())
|
||||
|
||||
def test_process_full_name_with_two_given_names(self):
|
||||
form = AddressForm(data={
|
||||
'full_name': 'John Doe',
|
||||
'email': 'john@example.com',
|
||||
'street_address_1': '1579 Talon Dr',
|
||||
'street_address_2': '',
|
||||
'city': 'Logan',
|
||||
'state': 'UT',
|
||||
'postal_code': '84321'
|
||||
})
|
||||
if form.is_valid():
|
||||
cleaned_data = form.cleaned_data
|
||||
first_name, last_name = form.process_full_name(
|
||||
cleaned_data.get('full_name')
|
||||
)
|
||||
self.assertEqual(first_name, 'John')
|
||||
self.assertEqual(last_name, 'Doe')
|
||||
|
||||
def test_process_full_name_with_more_than_two_given_names(self):
|
||||
form = AddressForm(data={
|
||||
'full_name': 'John Franklin Rosevelt Doe',
|
||||
'email': 'john@example.com',
|
||||
'street_address_1': '1579 Talon Dr',
|
||||
'street_address_2': '',
|
||||
'city': 'Logan',
|
||||
'state': 'UT',
|
||||
'postal_code': '84321'
|
||||
})
|
||||
if form.is_valid():
|
||||
cleaned_data = form.cleaned_data
|
||||
first_name, last_name = form.process_full_name(
|
||||
cleaned_data.get('full_name')
|
||||
)
|
||||
self.assertEqual(first_name, 'John Franklin Rosevelt')
|
||||
self.assertEqual(last_name, 'Doe')
|
||||
32
src/storefront/tests/test_views.py
Normal file
32
src/storefront/tests/test_views.py
Normal file
@ -0,0 +1,32 @@
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
|
||||
from django.test import TestCase, Client, RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
from measurement.measures import Weight
|
||||
from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
|
||||
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
|
||||
|
||||
from accounts.models import User, Address
|
||||
from core.models import Product, Order
|
||||
from core import CoffeeGrind
|
||||
from storefront.forms import AddressForm, OrderCreateForm
|
||||
from storefront.views import OrderCreateView, CheckoutAddressView
|
||||
from storefront.cart import Cart
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class CheckoutAddressViewTest(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
|
||||
def test_view_uses_correct_template(self):
|
||||
response = self.client.get(reverse('storefront:checkout-address'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'storefront/checkout_address.html')
|
||||
|
||||
def test_view_has_correct_form(self):
|
||||
response = self.client.get(reverse('storefront:checkout-address'))
|
||||
self.assertTrue(response.context['form'])
|
||||
self.assertTrue(isinstance(response.context['form'], AddressForm))
|
||||
@ -33,7 +33,8 @@ urlpatterns = [
|
||||
# path('delete/', views.CustomerDeleteView.as_view(), name='customer-delete'),
|
||||
|
||||
path('orders/<int:order_pk>/', views.OrderDetailView.as_view(), name='order-detail'),
|
||||
path('addresses/<int:address_pk>/update/', views.AddressUpdateView.as_view(), name='address-update'),
|
||||
path('addresses/new/', views.CustomerAddressCreateView.as_view(), name='customer-address-create'),
|
||||
path('addresses/<int:address_pk>/update/', views.CustomerAddressUpdateView.as_view(), name='address-update'),
|
||||
])),
|
||||
|
||||
]
|
||||
|
||||
@ -160,8 +160,7 @@ class CheckoutAddressView(FormView):
|
||||
if user.is_authenticated and user.default_shipping_address:
|
||||
address = user.default_shipping_address
|
||||
initial = {
|
||||
'first_name': address.first_name,
|
||||
'last_name': address.last_name,
|
||||
'full_name': address.first_name+' '+address.last_name,
|
||||
'email': user.email,
|
||||
'street_address_1': address.street_address_1,
|
||||
'street_address_2': address.street_address_2,
|
||||
@ -172,8 +171,7 @@ class CheckoutAddressView(FormView):
|
||||
elif self.request.session.get('shipping_address'):
|
||||
address = self.request.session.get('shipping_address')
|
||||
initial = {
|
||||
'first_name': address['first_name'],
|
||||
'last_name': address['last_name'],
|
||||
'full_name': address['first_name']+' '+address['last_name'],
|
||||
'email': address['email'],
|
||||
'street_address_1': address['street_address_1'],
|
||||
'street_address_2': address['street_address_2'],
|
||||
@ -185,7 +183,21 @@ class CheckoutAddressView(FormView):
|
||||
|
||||
def form_valid(self, form):
|
||||
# save address data to session
|
||||
self.request.session['shipping_address'] = form.cleaned_data
|
||||
cleaned_data = form.cleaned_data
|
||||
first_name, last_name = form.process_full_name(
|
||||
cleaned_data.get('full_name')
|
||||
)
|
||||
address = {
|
||||
'first_name': first_name,
|
||||
'last_name': last_name,
|
||||
'email': cleaned_data['email'],
|
||||
'street_address_1': cleaned_data['street_address_1'],
|
||||
'street_address_2': cleaned_data['street_address_2'],
|
||||
'city': cleaned_data['city'],
|
||||
'state': cleaned_data['state'],
|
||||
'postal_code': cleaned_data['postal_code']
|
||||
}
|
||||
self.request.session['shipping_address'] = address
|
||||
return super().form_valid(form)
|
||||
|
||||
class OrderCreateView(CreateView):
|
||||
@ -197,7 +209,9 @@ class OrderCreateView(CreateView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not self.request.session.get("shipping_address"):
|
||||
messages.warning(request, 'Please add a shipping address.')
|
||||
return HttpResponseRedirect(reverse('storefront:checkout-address'))
|
||||
return HttpResponseRedirect(
|
||||
reverse('storefront:checkout-address')
|
||||
)
|
||||
else:
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
@ -295,6 +309,7 @@ class CustomerUpdateView(LoginRequiredMixin, UpdateView):
|
||||
def get_success_url(self):
|
||||
return reverse('storefront:customer-detail', kwargs={'pk': self.object.pk})
|
||||
|
||||
|
||||
class OrderDetailView(LoginRequiredMixin, DetailView):
|
||||
model = Order
|
||||
template_name = 'storefront/order_detail.html'
|
||||
@ -305,7 +320,27 @@ class OrderDetailView(LoginRequiredMixin, DetailView):
|
||||
context['customer'] = User.objects.get(pk=self.kwargs['pk'])
|
||||
return context
|
||||
|
||||
class AddressUpdateView(LoginRequiredMixin, UpdateView):
|
||||
class CustomerAddressCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Address
|
||||
template_name = 'storefront/address_create_form.html'
|
||||
form_class = AccountAddressForm
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['customer'] = User.objects.get(pk=self.kwargs['pk'])
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
customer = User.objects.get(pk=self.kwargs['pk'])
|
||||
self.object = form.save()
|
||||
customer.addresses.add(self.object)
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('storefront:customer-detail', kwargs={'pk': self.kwargs['pk']})
|
||||
|
||||
class CustomerAddressUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Address
|
||||
pk_url_kwarg = 'address_pk'
|
||||
template_name = 'storefront/address_form.html'
|
||||
@ -317,7 +352,7 @@ class AddressUpdateView(LoginRequiredMixin, UpdateView):
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('storefront:customer-detail',kwargs={'pk': self.kwargs['pk']})
|
||||
return reverse('storefront:customer-detail', kwargs={'pk': self.kwargs['pk']})
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user