Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
thalia
concrexit
Commits
114140de
Commit
114140de
authored
Oct 12, 2017
by
Tom van Bussel
Browse files
activemembers: use User for foreign keys
parent
8e50bf43
Changes
16
Hide whitespace changes
Inline
Side-by-side
website/activemembers/admin.py
View file @
114140de
from
django.contrib
import
admin
from
django.forms
import
ModelForm
from
activemembers.forms
import
CommitteeMembershipForm
from
members.models
import
Member
from
utils.translation
import
TranslatedModelAdmin
from
.
import
models
class
CommitteeMembershipInlineForm
(
ModelForm
):
"""
Form for the Committee Membership inline
Doesn't do anything fancy, but we need it for speed.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
# Get the related fields in advance
self
.
fields
[
'member'
].
queryset
=
Member
.
objects
.
select_related
(
'user'
)
class
CommitteeMembershipInline
(
admin
.
StackedInline
):
model
=
models
.
CommitteeMembership
form
=
CommitteeMembershipInlineForm
can_delete
=
False
ordering
=
(
'since'
,)
extra
=
0
...
...
@@ -67,8 +51,8 @@ class CommitteeMembershipAdmin(TranslatedModelAdmin):
form
=
CommitteeMembershipForm
list_display
=
(
'member'
,
'committee'
,
'since'
,
'until'
,
'chair'
,
'role'
)
list_filter
=
(
'committee'
,)
search_fields
=
(
'member__
user__
first_name'
,
'member__
user__
last_name'
,
'member__
user__
email'
)
search_fields
=
(
'member__first_name'
,
'member__last_name'
,
'member__email'
)
@
admin
.
register
(
models
.
Mentorship
)
...
...
website/activemembers/backends.py
View file @
114140de
...
...
@@ -5,8 +5,6 @@ from django.contrib.auth.models import Permission
from
django.db.models
import
Q
from
django.utils
import
timezone
from
members.models
import
Member
class
CommitteeBackend
(
object
):
"""Check permissions against committees"""
...
...
@@ -23,13 +21,10 @@ class CommitteeBackend(object):
if
not
user
.
is_active
or
user
.
is_anonymous
or
obj
is
not
None
:
return
set
()
perm_cache_name
=
'_committee_perm_cache'
try
:
committees
=
user
.
member
.
committee_set
.
filter
(
Q
(
committeemembership__until
=
None
)
|
Q
(
committeemembership__until__gte
=
timezone
.
now
())
)
except
Member
.
DoesNotExist
:
return
set
()
committees
=
user
.
committee_set
.
filter
(
Q
(
committeemembership__until
=
None
)
|
Q
(
committeemembership__until__gte
=
timezone
.
now
())
)
if
not
hasattr
(
user
,
perm_cache_name
):
perms
=
(
Permission
.
objects
.
filter
(
committee__in
=
committees
)
...
...
website/activemembers/forms.py
View file @
114140de
from
django
import
forms
from
django.contrib.auth.models
import
User
from
activemembers.models
import
CommitteeMembership
from
members.models
import
Member
class
CommitteeMembershipForm
(
forms
.
ModelForm
):
member
=
forms
.
ModelChoiceField
(
queryset
=
Memb
er
.
objects
.
order_by
(
'
user__
first_name'
,
'user__
last_name'
))
queryset
=
Us
er
.
objects
.
order_by
(
'first_name'
,
'
last_name'
))
class
Meta
:
model
=
CommitteeMembership
...
...
website/activemembers/migrations/0022_0_user_foreign_keys.py
0 → 100644
View file @
114140de
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-10-11 18:50
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'activemembers'
,
'0021_auto_20170705_1902'
),
]
operations
=
[
migrations
.
AlterUniqueTogether
(
name
=
'mentorship'
,
unique_together
=
set
(),
),
migrations
.
AddField
(
model_name
=
'committee'
,
name
=
'members_old'
,
field
=
models
.
ManyToManyField
(
through
=
'activemembers.CommitteeMembership'
,
to
=
'members.Member'
,
null
=
True
,
related_name
=
'members_old'
),
),
migrations
.
AddField
(
model_name
=
'committeemembership'
,
name
=
'member_old'
,
field
=
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'members.Member'
,
verbose_name
=
'Member'
,
null
=
True
),
),
migrations
.
AddField
(
model_name
=
'mentorship'
,
name
=
'member_old'
,
field
=
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'members.Member'
,
verbose_name
=
'Member'
,
null
=
True
),
),
]
website/activemembers/migrations/0022_1_user_foreign_keys.py
0 → 100644
View file @
114140de
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-10-11 18:50
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
def
forward_func
(
apps
,
schema_editor
):
CommitteeMembership
=
apps
.
get_model
(
'activemembers'
,
'CommitteeMembership'
)
Mentorship
=
apps
.
get_model
(
'activemembers'
,
'Mentorship'
)
for
membership
in
CommitteeMembership
.
objects
.
all
():
membership
.
member_old
=
membership
.
member
membership
.
save
(
update_fields
=
(
'member_old'
,))
for
mentorship
in
Mentorship
.
objects
.
all
():
mentorship
.
member_old
=
mentorship
.
member
mentorship
.
save
(
update_fields
=
(
'member_old'
,))
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'activemembers'
,
'0022_0_user_foreign_keys'
),
]
operations
=
[
migrations
.
RunPython
(
code
=
forward_func
,
),
]
website/activemembers/migrations/0022_2_user_foreign_keys.py
0 → 100644
View file @
114140de
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-10-11 18:50
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'activemembers'
,
'0022_1_user_foreign_keys'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'committee'
,
name
=
'members'
,
),
migrations
.
RemoveField
(
model_name
=
'committeemembership'
,
name
=
'member'
,
),
migrations
.
RemoveField
(
model_name
=
'mentorship'
,
name
=
'member'
,
),
migrations
.
AddField
(
model_name
=
'committee'
,
name
=
'members'
,
field
=
models
.
ManyToManyField
(
through
=
'activemembers.CommitteeMembership'
,
to
=
settings
.
AUTH_USER_MODEL
,
null
=
True
),
),
migrations
.
AddField
(
model_name
=
'committeemembership'
,
name
=
'member'
,
field
=
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
settings
.
AUTH_USER_MODEL
,
verbose_name
=
'Member'
,
null
=
True
),
),
migrations
.
AddField
(
model_name
=
'mentorship'
,
name
=
'member'
,
field
=
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
settings
.
AUTH_USER_MODEL
,
verbose_name
=
'Member'
,
null
=
True
),
),
]
website/activemembers/migrations/0022_3_user_foreign_keys.py
0 → 100644
View file @
114140de
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-10-11 18:50
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
def
forward_func
(
apps
,
schema_editor
):
CommitteeMembership
=
apps
.
get_model
(
'activemembers'
,
'CommitteeMembership'
)
Mentorship
=
apps
.
get_model
(
'activemembers'
,
'Mentorship'
)
for
membership
in
CommitteeMembership
.
objects
.
all
():
membership
.
member
=
membership
.
member_old
.
user
membership
.
save
(
update_fields
=
(
'member'
,))
for
mentorship
in
Mentorship
.
objects
.
all
():
mentorship
.
member
=
mentorship
.
member_old
.
user
mentorship
.
save
(
update_fields
=
(
'member'
,))
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'activemembers'
,
'0022_2_user_foreign_keys'
),
]
operations
=
[
migrations
.
RunPython
(
code
=
forward_func
,
),
]
website/activemembers/migrations/0022_4_user_foreign_keys.py
0 → 100644
View file @
114140de
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-10-11 18:50
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'activemembers'
,
'0022_3_user_foreign_keys'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'committee'
,
name
=
'members_old'
,
),
migrations
.
RemoveField
(
model_name
=
'committeemembership'
,
name
=
'member_old'
,
),
migrations
.
RemoveField
(
model_name
=
'mentorship'
,
name
=
'member_old'
,
),
migrations
.
AlterUniqueTogether
(
name
=
'mentorship'
,
unique_together
=
set
([(
'member'
,
'year'
)]),
),
]
website/activemembers/models.py
View file @
114140de
import
datetime
import
logging
from
django.contrib.auth.models
import
Permission
from
django.contrib.auth.models
import
Permission
,
User
from
django.core.exceptions
import
NON_FIELD_ERRORS
,
ValidationError
from
django.core.validators
import
MinValueValidator
from
django.db
import
models
...
...
@@ -69,7 +69,7 @@ class Committee(models.Model, metaclass=ModelTranslateMeta):
)
members
=
models
.
ManyToManyField
(
'members.Memb
er
'
,
Us
er
,
through
=
'CommitteeMembership'
)
...
...
@@ -206,7 +206,7 @@ class CommitteeMembership(models.Model, metaclass=ModelTranslateMeta):
active_memberships
=
ActiveMembershipManager
()
member
=
models
.
ForeignKey
(
'members.Memb
er
'
,
Us
er
,
on_delete
=
models
.
CASCADE
,
verbose_name
=
_
(
'Member'
),
)
...
...
@@ -329,11 +329,11 @@ class CommitteeMembership(models.Model, metaclass=ModelTranslateMeta):
def
save
(
self
,
*
args
,
**
kwargs
):
super
().
save
(
*
args
,
**
kwargs
)
self
.
member
.
user
.
is_staff
=
(
self
.
member
.
committeemembership_set
.
exclude
(
until__lte
=
timezone
.
now
().
date
())
.
count
())
>=
1
self
.
member
.
user
.
save
()
self
.
member
.
is_staff
=
(
self
.
member
.
committeemembership_set
.
exclude
(
until__lte
=
timezone
.
now
().
date
())
.
count
())
>=
1
self
.
member
.
save
()
def
__str__
(
self
):
return
"{} membership of {} since {}, until {}"
.
format
(
self
.
member
,
...
...
@@ -348,7 +348,7 @@ class CommitteeMembership(models.Model, metaclass=ModelTranslateMeta):
class
Mentorship
(
models
.
Model
):
member
=
models
.
ForeignKey
(
'members.Memb
er
'
,
Us
er
,
on_delete
=
models
.
CASCADE
,
verbose_name
=
_
(
'Member'
),
)
...
...
website/activemembers/templates/activemembers/board_detail.html
View file @
114140de
...
...
@@ -34,13 +34,13 @@
<ul
class=
"row"
id=
"commissieleden"
>
{% for member in members %}
<li
class=
"post member-item span3 has-overlay"
>
<a
href=
"{{ member.get_absolute_url }}"
>
<a
href=
"{{
member.
member.get_absolute_url }}"
>
<div
class=
"post-inner"
>
<div
class=
"inner-img"
>
{% if not member.photo %}
<img
alt=
"{{ member.display_name }}"
src=
"{% static 'members/images/default-avatar.jpg' %}"
height=
"220"
width=
"220"
/>
{% if not
member.
member.photo %}
<img
alt=
"{{
member.
member.display_name }}"
src=
"{% static 'members/images/default-avatar.jpg' %}"
height=
"220"
width=
"220"
/>
{% else %}
<img
alt=
"{{ member.display_name }}"
src=
"{% thumbnail member.photo '220x220' %}"
width=
"220"
height=
"220"
/>
<img
alt=
"{{
member.
member.display_name }}"
src=
"{% thumbnail
member.
member.photo '220x220' %}"
width=
"220"
height=
"220"
/>
{% endif %}
</div>
{% if member.chair %}
...
...
@@ -52,12 +52,12 @@
{% endif %}
<div
class=
"post-overlay"
>
<div
class=
"post-overlay-meta"
>
<h2>
{{ member.display_name }}
</h2>
<h2>
{{
member.
member.display_name }}
</h2>
<p>
{{ member.role }}
</p>
</div>
</div>
<div
class=
"post-body avatar-subtitle"
>
{{ member.display_name }}
{{
member.
member.display_name }}
</div>
</div>
</a>
...
...
website/activemembers/templates/activemembers/committee_detail.html
View file @
114140de
...
...
@@ -30,13 +30,13 @@
<ul
class=
"row"
id=
"commissieleden"
>
{% for member in members %}
<li
class=
"post member-item span3 has-overlay"
>
<a
href=
"{{ member.get_absolute_url }}"
>
<a
href=
"{{
member.
member.get_absolute_url }}"
>
<div
class=
"post-inner"
>
<div
class=
"inner-img"
>
{% if not member.photo %}
<img
alt=
"{{ member.display_name }}"
src=
"{% static 'members/images/default-avatar.jpg' %}"
height=
"220"
width=
"220"
/>
{% if not
member.
member.photo %}
<img
alt=
"{{
member.
member.display_name }}"
src=
"{% static 'members/images/default-avatar.jpg' %}"
height=
"220"
width=
"220"
/>
{% else %}
<img
alt=
"{{ member.display_name }}"
src=
"{% thumbnail member.photo '220x220' %}"
width=
"220"
height=
"220"
/>
<img
alt=
"{{
member.
member.display_name }}"
src=
"{% thumbnail
member.
member.photo '220x220' %}"
width=
"220"
height=
"220"
/>
{% endif %}
</div>
{% if member.chair %}
...
...
@@ -48,7 +48,7 @@
{% endif %}
<div
class=
"post-overlay"
>
<div
class=
"post-overlay-meta"
>
<h2>
{{ member.display_name }}
</h2>
<h2>
{{
member.
member.display_name }}
</h2>
<p>
{% if member.committee_since.year == 1970 %}
{% blocktrans %}Committee member since: ?{% endblocktrans %}
...
...
@@ -59,7 +59,7 @@
</div>
</div>
<div
class=
"post-body avatar-subtitle"
>
{{ member.display_name }}
{{
member.
member.display_name }}
</div>
</div>
</a>
...
...
website/activemembers/tests.py
View file @
114140de
from
django.contrib.auth
import
get_user_model
from
django.contrib.auth.models
import
User
from
django.core.exceptions
import
ValidationError
from
django.db.utils
import
IntegrityError
from
django.test
import
TestCase
...
...
@@ -6,7 +7,6 @@ from django.utils import timezone
from
activemembers.models
import
Committee
,
CommitteeMembership
,
Board
from
mailinglists.models
import
MailingList
from
members.models
import
Member
class
CommitteeMembersTest
(
TestCase
):
...
...
@@ -15,7 +15,7 @@ class CommitteeMembersTest(TestCase):
@
classmethod
def
setUpTestData
(
cls
):
cls
.
testcie
=
Committee
.
objects
.
get
(
pk
=
1
)
cls
.
testuser
=
Memb
er
.
objects
.
get
(
pk
=
1
)
cls
.
testuser
=
Us
er
.
objects
.
get
(
pk
=
1
)
cls
.
m
=
CommitteeMembership
.
objects
.
create
(
committee
=
cls
.
testcie
,
member
=
cls
.
testuser
,
...
...
@@ -35,7 +35,7 @@ class CommitteeMembersTest(TestCase):
photo
=
""
)
def
test_join
(
self
):
testuser2
=
Memb
er
.
objects
.
get
(
pk
=
2
)
testuser2
=
Us
er
.
objects
.
get
(
pk
=
2
)
m
=
CommitteeMembership
(
committee
=
self
.
testcie
,
member
=
testuser2
)
m
.
full_clean
()
...
...
@@ -95,8 +95,8 @@ class CommitteeMembersChairTest(TestCase):
@
classmethod
def
setUpTestData
(
cls
):
cls
.
testcie
=
Committee
.
objects
.
get
(
pk
=
1
)
cls
.
testuser
=
Memb
er
.
objects
.
get
(
pk
=
1
)
cls
.
testuser2
=
Memb
er
.
objects
.
get
(
pk
=
2
)
cls
.
testuser
=
Us
er
.
objects
.
get
(
pk
=
1
)
cls
.
testuser2
=
Us
er
.
objects
.
get
(
pk
=
2
)
def
setUp
(
self
):
self
.
m1
=
CommitteeMembership
(
committee
=
self
.
testcie
,
...
...
@@ -134,11 +134,11 @@ class PermissionsBackendTest(TestCase):
@
classmethod
def
setUpTestData
(
cls
):
cls
.
u1
=
Memb
er
.
objects
.
get
(
pk
=
1
)
cls
.
u1
.
user
.
is_superuser
=
False
cls
.
u1
=
Us
er
.
objects
.
get
(
pk
=
1
)
cls
.
u1
.
is_superuser
=
False
cls
.
u1
.
save
()
cls
.
u2
=
Memb
er
.
objects
.
get
(
pk
=
2
)
cls
.
u3
=
Memb
er
.
objects
.
get
(
pk
=
3
)
cls
.
u2
=
Us
er
.
objects
.
get
(
pk
=
2
)
cls
.
u3
=
Us
er
.
objects
.
get
(
pk
=
3
)
cls
.
c1
=
Committee
.
objects
.
get
(
pk
=
1
)
cls
.
c2
=
Committee
.
objects
.
get
(
pk
=
2
)
cls
.
m1
=
CommitteeMembership
.
objects
.
create
(
committee
=
cls
.
c1
,
...
...
@@ -147,9 +147,9 @@ class PermissionsBackendTest(TestCase):
member
=
cls
.
u2
)
def
test_permissions
(
self
):
self
.
assertEqual
(
3
,
len
(
self
.
u1
.
user
.
get_all_permissions
()))
self
.
assertEqual
(
set
(),
self
.
u2
.
user
.
get_all_permissions
())
self
.
assertEqual
(
set
(),
self
.
u3
.
user
.
get_all_permissions
())
self
.
assertEqual
(
3
,
len
(
self
.
u1
.
get_all_permissions
()))
self
.
assertEqual
(
set
(),
self
.
u2
.
get_all_permissions
())
self
.
assertEqual
(
set
(),
self
.
u3
.
get_all_permissions
())
def
test_nonmember_user
(
self
):
u
=
get_user_model
().
objects
.
create
(
username
=
'foo'
)
...
...
website/events/tests/test_views.py
View file @
114140de
...
...
@@ -39,6 +39,7 @@ class AdminTest(TestCase):
price
=
0.00
,
fine
=
0.00
)
cls
.
member
=
Member
.
objects
.
filter
(
user__last_name
=
"Wiggers"
).
first
()
cls
.
user
=
cls
.
member
.
user
cls
.
permission_change_event
=
Permission
.
objects
.
get
(
content_type__model
=
'event'
,
codename
=
'change_event'
)
...
...
@@ -71,7 +72,7 @@ class AdminTest(TestCase):
def
test_admin_details_organiser_allowed
(
self
):
CommitteeMembership
.
objects
.
create
(
member
=
self
.
memb
er
,
member
=
self
.
us
er
,
committee
=
self
.
committee
)
response
=
self
.
client
.
get
(
'/events/admin/1/'
)
self
.
assertEqual
(
200
,
response
.
status_code
)
...
...
@@ -87,7 +88,7 @@ class AdminTest(TestCase):
If I'm an organiser I should be allowed access
"""
CommitteeMembership
.
objects
.
create
(
member
=
self
.
memb
er
,
member
=
self
.
us
er
,
committee
=
self
.
committee
)
response
=
self
.
client
.
get
(
'/admin/events/event/1/change/'
)
self
.
assertEqual
(
200
,
response
.
status_code
)
...
...
@@ -109,7 +110,7 @@ class AdminTest(TestCase):
"""
self
.
_remove_event_permission
()
CommitteeMembership
.
objects
.
create
(
member
=
self
.
memb
er
,
member
=
self
.
us
er
,
committee
=
self
.
committee
)
response
=
self
.
client
.
get
(
'/admin/events/event/1/change/'
)
self
.
assertEqual
(
403
,
response
.
status_code
)
...
...
website/mailinglists/services.py
View file @
114140de
...
...
@@ -12,7 +12,7 @@ def get_automatic_lists():
.
filter
(
committee__board
=
None
)
.
filter
(
chair
=
True
)
.
prefetch_related
(
'member__user'
))
committee_chairs
=
[
x
.
member
for
x
in
memberships
]
+
[
Member
(
committee_chairs
=
[
x
.
member
.
member
for
x
in
memberships
]
+
[
Member
(
user
=
User
(
email
=
'intern@thalia.nu'
)
...
...
@@ -20,8 +20,8 @@ def get_automatic_lists():
active_committee_memberships
=
(
CommitteeMembership
.
active_memberships
.
exclude
(
committee__board__is_board
=
True
)
.
prefetch_related
(
'member__
us
er'
))
active_members
=
[
x
.
member
for
x
in
active_committee_memberships
]
.
prefetch_related
(
'member__
memb
er'
))
active_members
=
[
x
.
member
.
member
for
x
in
active_committee_memberships
]
lectureyear
=
datetime_to_lectureyear
(
timezone
.
now
())
# Change to next lecture year after December
...
...
@@ -29,7 +29,7 @@ def get_automatic_lists():
lectureyear
+=
1
active_mentorships
=
Mentorship
.
objects
.
filter
(
year
=
lectureyear
)
mentors
=
[
x
.
member
for
x
in
active_mentorships
]
mentors
=
[
x
.
member
.
member
for
x
in
active_mentorships
]
lists
=
[]
...
...
website/members/models.py
View file @
114140de
...
...
@@ -368,7 +368,7 @@ class Member(models.Model):
def
get_committees
(
self
):
return
Committee
.
unfiltered_objects
.
filter
(
Q
(
committeemembership__member
=
self
)
&
Q
(
committeemembership__member
=
self
.
user
)
&
(
Q
(
committeemembership__until
=
None
)
|
Q
(
committeemembership__until__gt
=
timezone
.
now
())
...
...
website/utils/management/commands/createfixtures.py
View file @
114140de
...
...
@@ -335,14 +335,14 @@ class Command(BaseCommand):
self
.
create_user
()
if
options
[
'board'
]:
members
=
Memb
er
.
objects
.
all
()
members
=
Us
er
.
objects
.
all
()
lecture_year
=
datetime_to_lectureyear
(
date
.
today
())
for
i
in
range
(
options
[
'board'
]):
self
.
create_board
(
lecture_year
-
i
,
members
)
# Committees need to be generated before events
if
options
[
'committee'
]:
members
=
Memb
er
.
objects
.
all
()
members
=
Us
er
.
objects
.
all
()
for
__
in
range
(
options
[
'committee'
]):
self
.
create_committee
(
members
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment