Skip to content

Commit a805526

Browse files
authored
Merge pull request #363 from pythoncanarias/issue#362
Add Class-based view to update address and phone
2 parents ce5f2c5 + e981a82 commit a805526

12 files changed

Lines changed: 151 additions & 7 deletions

File tree

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"settings": {
88
"editor.formatOnSave": true,
99
// Python
10-
"python.pythonPath": "/opt/venv/bin/python",
10+
"python.defaultInterpreterPath": "/opt/venv/bin/python",
1111
"[python]": {
1212
"editor.codeActionsOnSave": {
1313
"source.organizeImports": true
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{% if errors %}
2+
<ul class="errorlist">
3+
{% for error in errors %}
4+
<li>{{ error }}</li>
5+
{% endfor %}
6+
</ul>
7+
{% endif %}

apps/commons/templatetags/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,11 @@ def is_active(context, named_url):
3333
return 'is-active'
3434
else:
3535
return ''
36+
37+
38+
@register.inclusion_tag('includes/error_list.html')
39+
def error_list(field):
40+
print(field, type(field))
41+
return {
42+
'errors': field.errors,
43+
}

apps/members/forms.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from django.contrib.auth import authenticate, update_session_auth_hash
44
from django.core.exceptions import ValidationError
55

6+
from .models import Member
7+
68
MIN_PASSWORD_LENGTH = 8
79

810
# Validation error messages
@@ -150,3 +152,23 @@ def save(self, request):
150152
self.user.save()
151153
update_session_auth_hash(request, self.user)
152154
messages.success(request, "Contraseña cambiada correctamente")
155+
156+
157+
class ChangeAddressForm(forms.ModelForm):
158+
class Meta:
159+
model = Member
160+
fields = [
161+
'address',
162+
'rest_address',
163+
'postal_code',
164+
'city',
165+
'phone',
166+
]
167+
168+
address = forms.CharField(label='Dirección<sup>*</sup>', strip=True)
169+
rest_address = forms.CharField(label='(extra)', required=False, strip=True)
170+
postal_code = forms.CharField(
171+
label="Cód. postal<sup>*</sup>", max_length=12, strip=True
172+
)
173+
city = forms.CharField(label='Ciudad<sup>*</sup>', strip=True)
174+
phone = forms.CharField(label='Teléfono', required=False, strip=True)

apps/members/menu.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
.finished()
99
.add_section('ops', 'Operaciones')
1010
.add_menu_item("Cambiar contraseña", "members:password_change")
11+
.add_menu_item("Cambiar dirección", "members:address_change")
1112
.add_menu_item("Salir (<i>Logout</i>)", "members:logout")
1213
.finished()
1314
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
11
@import 'apps/commons/static/commons/css/base';
2+
3+
.pb-vertical {
4+
flex-direction: column;
5+
align-items: baseline;
6+
}
7+
8+
.rest-address-label {
9+
margin-top: 1rem;
10+
font-weight: 100;
11+
}
12+
13+
.phone-label {
14+
font-weight: 100;
15+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{% extends 'members/base.html' %}
2+
{% load utils %}
3+
4+
{% block content %}
5+
<div class="box">
6+
7+
<nav class="panel">
8+
<h3 class="panel-heading">Dirección postal y teléfono</h3>
9+
<div class="panel-block">
10+
<form class="form" method="POST" action=".">
11+
{% csrf_token %}
12+
13+
{% for hidden in form.hidden_fields %}
14+
{{ hidden }}
15+
{% endfor %}
16+
17+
<table class="table">
18+
19+
<tr>
20+
<th>
21+
{{ form.address.label|safe }}
22+
<div class="rest-address-label">{{ form.rest_address.label|safe }}</div>
23+
</th>
24+
<td>
25+
<input name="address" class="input" type="text" value="{{ form.address.value }}">
26+
{% error_list form.address %}
27+
<input name="rest_address" class="input" type="text" value="{{ form.rest_address.value }}">
28+
{% error_list form.rest_address %}
29+
</tr>
30+
31+
<tr>
32+
<th>{{ form.postal_code.label|safe }}</th>
33+
<td>
34+
<input name="postal_code" class="input" type="text" value="{{ form.postal_code.value }}">
35+
{% error_list form.postal_code %}
36+
</td>
37+
</tr>
38+
39+
<tr>
40+
<th>{{ form.city.label|safe }}</th>
41+
<td>
42+
<input name="city" class="input" type="text" value="{{ form.city.value }}">
43+
{% error_list form.city %}
44+
</td>
45+
</tr>
46+
47+
<tr>
48+
<th class="phone-label">{{ form.phone.label|safe }}</th>
49+
<td>
50+
<input name="phone" class="input" type="text" value="{{ form.phone.value }}">
51+
{% error_list form.phone %}
52+
</td>
53+
</tr>
54+
55+
</table>
56+
57+
<button type="submit" role="button" class="button is-link is-outlined">Cambiar dirección</button>
58+
59+
</form>
60+
</div>
61+
</nav>
62+
</div>
63+
64+
{% endblock content %}

apps/members/templates/members/profile.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ <h3 class="panel-heading">Datos personales</h3>
1919

2020
<nav class="panel">
2121
<h3 class="panel-heading">Socio/a: #{{ member.pk }}</h3>
22-
<div class="panel-block">
23-
22+
<div class="panel-block pb-vertical">
2423
<table class="table table-striped">
2524
<tr>
2625
<th>Dirección</th>
@@ -43,9 +42,10 @@ <h3 class="panel-heading">Socio/a: #{{ member.pk }}</h3>
4342
<td>{{ member.phone|default:"No disponible" }}</td>
4443
</tr>
4544
</table>
45+
46+
<a href="{% url 'members:address_change' %}"><i class="fas fa-edit"></i> Actualizar datos</a>
4647
</div>
4748
</nav>
48-
4949
</div>
5050

5151
{% endblock content %}

apps/members/urls.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
path("profile/", views.profile, name="profile"),
1010
path("membership/", views.view_membership, name="membership"),
1111
path("password/change/", views.password_change, name="password_change"),
12+
path(
13+
"address/change/", views.ChangeAddress.as_view(), name="address_change"
14+
),
1215
path("login/", views.member_login, name="login"),
1316
path("logout/", views.member_logout, name="logout"),
1417
]

apps/members/views.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from django.core.exceptions import PermissionDenied
77
from django.http import HttpRequest, HttpResponse
88
from django.shortcuts import redirect, render
9-
from django.urls import reverse
9+
from django.urls import reverse, reverse_lazy
10+
from django.views.generic import UpdateView
1011

1112
from . import forms
1213
from .menu import main_menu
@@ -104,3 +105,27 @@ def password_change(request):
104105
"menu": main_menu,
105106
},
106107
)
108+
109+
110+
class ChangeAddress(UpdateView):
111+
form_class = forms.ChangeAddressForm
112+
template_name = 'members/address-change.html'
113+
114+
def get_success_url(self):
115+
return reverse_lazy('members:profile')
116+
117+
def get_object(self, queryset=None):
118+
return self.request.user.member
119+
120+
def form_invalid(self, form):
121+
num_errors = sum(len(err) for err in form.errors.values())
122+
messages.error(
123+
self.request, f'El formulario tiene {num_errors} errores'
124+
)
125+
return super().form_invalid(form)
126+
127+
def get_context_data(self, **kwargs):
128+
context = {
129+
'menu': main_menu,
130+
}
131+
return super().get_context_data(**context)

0 commit comments

Comments
 (0)