Skip to content

Commit ee7a878

Browse files
author
Marie Klaus
committed
Implement working change password.
1 parent 5720d7a commit ee7a878

File tree

14 files changed

+207
-160
lines changed

14 files changed

+207
-160
lines changed

accounts/admin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.contrib import admin
22
from django.contrib.auth import get_user_model
33
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
4-
from .models import Department, Profile
4+
from .models import Department, Profile, ProfileDepartment
55
from .forms import UserCreationForm, UserChangeForm
66

77
# load custom user model
@@ -45,3 +45,4 @@ class UserAdmin(BaseUserAdmin):
4545
# admin.site.register(UserManager)
4646
admin.site.register(Department)
4747
admin.site.register(Profile)
48+
admin.site.register(ProfileDepartment)

accounts/forms.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class UpdateUserForm(UserChangeForm):
165165

166166
class Meta:
167167
model = User
168-
fields = ('first_name', 'last_name', 'email', 'password')
168+
fields = ('first_name', 'last_name', 'email')
169169
widgets = {
170170
'first_name': forms.TextInput(
171171
attrs = {
@@ -250,18 +250,20 @@ def clean_avatar(self):
250250

251251
return avatar
252252

253+
### TO DO:
253254
###### CHANGE PROFILE_DEPARTMENT FORM ######
254-
class ProfileDepartmentChangeForm(forms.ModelForm):
255+
# class ProfileDepartmentChangeForm(forms.ModelForm):
255256

256-
DEPARTMENT_CHOICES = [[department.id, department.department_name] for department in Department.objects.all()]
257+
# DEPARTMENT_CHOICES = [(department.id, department.department_name) for department in Department.objects.all()]
258+
# # DEPARTMENT_CHOICES = [(1, 'SE'), (2,'PM')]
257259

258-
department = forms.MultipleChoiceField(
259-
required = False,
260-
widget=forms.CheckboxSelectMultiple,
261-
choices=DEPARTMENT_CHOICES
262-
)
260+
# departments = forms.MultipleChoiceField(
261+
# required = False,
262+
# widget=forms.CheckboxSelectMultiple,
263+
# choices=DEPARTMENT_CHOICES
264+
# )
263265

264-
class Meta:
265-
model = ProfileDepartment
266-
fields = ('department',)
266+
# class Meta:
267+
# model = ProfileDepartment
268+
# fields = ('departments',)
267269

accounts/migrations/0001_initial.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 2.1.2 on 2018-12-02 16:02
1+
# Generated by Django 2.1.2 on 2018-12-03 21:40
22

33
from django.conf import settings
44
from django.db import migrations, models
@@ -39,23 +39,31 @@ class Migration(migrations.Migration):
3939
('department_name', models.CharField(max_length=32)),
4040
],
4141
),
42+
migrations.CreateModel(
43+
name='Expertise',
44+
fields=[
45+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
46+
],
47+
),
4248
migrations.CreateModel(
4349
name='Profile',
4450
fields=[
4551
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
4652
('occupation', models.CharField(blank=True, choices=[('STUDENT', 'Student'), ('CD', 'Code+Design Camper'), ('AC_STAFF', 'Academic Team'), ('ADMIN_STAFF', 'Code Administration Team'), ('ALUMNI', 'Alumni'), ('EXTERNAL', 'External')], default='STUDENT', max_length=32, null=True)),
47-
('institution', models.CharField(blank=True, choices=[('CODE', 'Code University'), ('CD', 'Code+Design Camps'), ('OTHER', 'other')], default='CODE', max_length=32, null=True)),
53+
('institution', models.CharField(blank=True, choices=[('CODE', 'CODE University Berlin'), ('CD', 'Code+Design Camps'), ('OTHER', 'other')], default='CODE', max_length=32, null=True)),
4854
('avatar', models.ImageField(blank=True, null=True, upload_to='profile_images')),
4955
('last_modified', models.DateTimeField(auto_now=True)),
5056
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
5157
],
5258
),
53-
migrations.CreateModel(
54-
name='ProfileDepartment',
55-
fields=[
56-
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
57-
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Department')),
58-
('profile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Profile')),
59-
],
59+
migrations.AddField(
60+
model_name='expertise',
61+
name='current_profile',
62+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owner', to='accounts.Profile'),
63+
),
64+
migrations.AddField(
65+
model_name='expertise',
66+
name='departments',
67+
field=models.ManyToManyField(to='accounts.Department'),
6068
),
6169
]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 2.1.2 on 2018-12-03 21:53
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('accounts', '0001_initial'),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='ProfileDepartment',
16+
fields=[
17+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('current_profile', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='accounts.Profile')),
19+
('departments', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Department')),
20+
],
21+
),
22+
migrations.RemoveField(
23+
model_name='expertise',
24+
name='current_profile',
25+
),
26+
migrations.RemoveField(
27+
model_name='expertise',
28+
name='departments',
29+
),
30+
migrations.DeleteModel(
31+
name='Expertise',
32+
),
33+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 2.1.2 on 2018-12-03 21:56
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('accounts', '0002_auto_20181203_2253'),
10+
]
11+
12+
operations = [
13+
migrations.RenameField(
14+
model_name='profiledepartment',
15+
old_name='current_profile',
16+
new_name='profile',
17+
),
18+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 2.1.2 on 2018-12-04 08:35
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('accounts', '0003_auto_20181203_2256'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='profiledepartment',
15+
name='departments',
16+
),
17+
migrations.AddField(
18+
model_name='profiledepartment',
19+
name='departments',
20+
field=models.ManyToManyField(to='accounts.Department'),
21+
),
22+
]

accounts/models.py

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from django.db import models
2-
from enum import Enum
2+
from django.forms.models import model_to_dict
33
# use Django signals to extend User object
44
from django.db.models.signals import post_save
55
from django.contrib.auth.models import (
@@ -103,7 +103,7 @@ def is_active(self):
103103

104104
class Department(models.Model):
105105
department_name = models.CharField(max_length=32)
106-
106+
107107
def __str__(self):
108108
return self.department_name
109109

@@ -138,22 +138,77 @@ class Profile(models.Model):
138138
institution = models.CharField(max_length=32, null=True, blank=True, choices=INSTITUTION_CHOICES, default=CODE)
139139
avatar = models.ImageField(upload_to='profile_images', null=True, blank=True)
140140
last_modified = models.DateTimeField(auto_now=True)
141-
142-
# def get_occupation_di(self):
143-
# (occupation, occupation.value) for occupation in OCCUPATION_CHOICES:
144-
# return self.occupation.value
145-
146141

147142
# TO DO PROVIDE PROFILECHANGEFORM FOR ADMIN
148143
# def __str__(self):
149144
# return self.user
150145

151146
class ProfileDepartment(models.Model):
152-
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
153-
department = models.ForeignKey(Department, on_delete=models.CASCADE)
147+
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
148+
departments = models.ManyToManyField(Department)
154149

155-
def __str__(self):
156-
return "%s %s" % (self.profile, self.department)
150+
@classmethod
151+
def add_department(cls, profile, new_department):
152+
profile_department, created = cls.objects.get_or_create(
153+
profile=profile
154+
)
155+
profile_department.departments.add(new_department)
156+
157+
@classmethod
158+
def remove_department(cls, profile, department):
159+
profile_department, created = cls.objects.get_or_create(
160+
profile=profile
161+
)
162+
profile_department.departments.remove(department)
163+
164+
# def __str__(self):
165+
# return "%s %s" % (self.profile.user, self.departments)
166+
167+
####### Mixins ##########
168+
169+
# source:
170+
# https://stackoverflow.com/questions/1355150/django-when-saving-how-can-you-check-if-a-field-has-changed
171+
172+
# class ModelDiffMixin(object):
173+
# """A model mixin that tracks model fields' values
174+
# and whether fields have been changed."""
175+
176+
# def __init__(self, *args, **kwargs):
177+
# super(ModelDiffMixins, self).__init__(*args, **kwargs)
178+
# self.__initial = self.dict
179+
180+
# @property
181+
# def diff(self):
182+
# d1 = self.__initial
183+
# d2 = self._dict
184+
# diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]]
185+
# return dict(diffs)
186+
187+
# @property
188+
# def has_changed(self):
189+
# return bool(self.diff)
190+
191+
# @property
192+
# def changed_fields(self):
193+
# return self.diff.keys()
194+
195+
# def get_field_diff(self, field_name):
196+
# """
197+
# Returns a diff for field if it's changed and None otherwise.
198+
# """
199+
# return self.diff.get(field_name, None)
200+
201+
# def save(self, *args, **kwargs):
202+
# """
203+
# Saves model and set initial state.
204+
# """
205+
# super(ModelDiffMixin, self).save(*args, **kwargs)
206+
# self.__initial = self._dict
207+
208+
# @property
209+
# def _dict(self):
210+
# return model_to_dict(self,
211+
# fields=[field.name for field in self._meta.fields])
157212

158213
# Trigger creation of corresponding user profile as soon as Django User object has been created.
159214
def create_profile(sender, **kwargs):

accounts/templates/change_password.html

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,60 +15,29 @@ <h2 style="margin: auto; "> Change password </h2>
1515
<img src="{% static 'outline_account_circle.png' %}"/>
1616
</div>
1717
</div>
18-
{% if error %}
19-
<div class="alert alert-warning" role="alert">
20-
{{ error }}
21-
</div>
22-
{% endif %}
23-
{% if success %}
24-
<div class="alert alert-success" role="alert">
25-
{{ success }}
26-
</div>
18+
{% if messages %}
19+
<ul class="messages">
20+
{% for message in messages %}
21+
<li{% if message.tag %} class="{{ message.tag }}"{% endif %}>{{ message }}</li>
22+
{% endfor %}
23+
</ul>
2724
{% endif %}
2825

2926
<hr />
3027

3128
<form class="" style="margin: auto; width: 100%;"
32-
method="POST" action="{% url 'profile' %}">
29+
method="POST" action="{% url 'change_password'%}">
3330
{% csrf_token %}
3431
{{form.as_p}}
35-
<!-- <div class="form-group">
36-
<label for="first_name" style="font-size: 10px;">First name</label>
37-
<p>{{user_form.first_name}}</p>
38-
<p>{{user_form.first_name.errors}}</p>
39-
<hr>
40-
</div>
41-
<div class="form-group">
42-
<label for="last_name" style="font-size: 10px;">Last name</label>
43-
<p>{{user_form.last_name}}</p>
44-
<p>{{user_form.last_name.errors}}</p>
45-
<hr>
46-
</div>
47-
<div class="form-group">
48-
<label for="email" style="font-size: 10px;">Email</label>
49-
<p>{{user_form.email}}</p>
50-
<p>{{user_form.email.errors}}</p>
51-
<hr>
52-
</div>
53-
<div class="form-group">
54-
<label for="password-confirm" style="font-size: 10px;">Enter your password to confirm changes.</label>
55-
<p>{{user_form.password_confirm}}</p>
56-
<p>{{user_form.password_confirm.errors}}</p>
57-
<hr>
58-
</div> -->
5932
<div class="form-row">
6033
<input
6134
class="btn btn-primary animated pulse"
6235
style="background: linear-gradient(to right, rgb(36, 198, 220), rgb(81, 74, 157));
6336
margin: 0 auto; width: 60%;"
6437
type="submit"
65-
value="Submit changes"/>
38+
value="Reset password"/>
6639
</div>
6740
</form>
68-
<!-- <a href="">Change password</a> -->
69-
<!-- <a onclick="javascript:window.location.href='{% url 'change_password' %}';">Change password</a> -->
70-
71-
<a class="pl-3"><img src="{% static 'outline_edit.png' %}"/></a>
7241
</div>
7342
</div>
7443
{% endblock %}

accounts/templates/profile.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,6 @@ <h3 style="margin: auto; "> {{user.first_name}} {{user.last_name}} </h3>
7272
<p>{{profile_form.avatar}}</p>
7373
<p>{{profile_form.avatar.errors}}</p>
7474
</div>
75-
<div class="form-check">
76-
<label for="select-department" style="font-size: 10px;">Your study program or field of expertise.</label>
77-
<p>{{prof_dep_form.department}}</p>
78-
<p>{{prof_dep_form.department.errors}}</p>
79-
</div>
8075
<br>
8176
<div class="form-row">
8277
<input

accounts/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
path('logout', views.logout, name='logout'),
77
path('signup', views.signup, name='signup'),
88
path('profile', views.profile_edit, name='profile'),
9-
path('change-password', views.change_password, name='change_password'),
9+
path('password', views.change_password, name='change_password'),
1010
]

0 commit comments

Comments
 (0)