Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
ce8f3112
Commit
ce8f3112
authored
Aug 14, 2015
by
Diana Huang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a new last_activity_at field.
TNL-3068
parent
50e7a9d6
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
158 additions
and
8 deletions
+158
-8
lms/djangoapps/teams/migrations/0004_auto__add_field_courseteam_discussion_topic_id__add_field_courseteam_l.py
+94
-0
lms/djangoapps/teams/models.py
+12
-1
lms/djangoapps/teams/serializers.py
+4
-3
lms/djangoapps/teams/tests/factories.py
+7
-0
lms/djangoapps/teams/tests/test_models.py
+17
-3
lms/djangoapps/teams/tests/test_views.py
+12
-1
lms/djangoapps/teams/views.py
+12
-0
No files found.
lms/djangoapps/teams/migrations/0004_auto__add_field_courseteam_discussion_topic_id__add_field_courseteam_l.py
0 → 100644
View file @
ce8f3112
# -*- coding: utf-8 -*-
import
pytz
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding field 'CourseTeam.last_activity_at'
db
.
add_column
(
'teams_courseteam'
,
'last_activity_at'
,
self
.
gf
(
'django.db.models.fields.DateTimeField'
)(
default
=
datetime
.
datetime
(
2015
,
8
,
17
,
0
,
0
)
.
replace
(
tzinfo
=
pytz
.
utc
)),
keep_default
=
False
)
# Adding field 'CourseTeamMembership.last_activity_at'
db
.
add_column
(
'teams_courseteammembership'
,
'last_activity_at'
,
self
.
gf
(
'django.db.models.fields.DateTimeField'
)(
default
=
datetime
.
datetime
(
2015
,
8
,
17
,
0
,
0
)
.
replace
(
tzinfo
=
pytz
.
utc
)),
keep_default
=
False
)
def
backwards
(
self
,
orm
):
# Deleting field 'CourseTeam.last_activity_at'
db
.
delete_column
(
'teams_courseteam'
,
'last_activity_at'
)
# Deleting field 'CourseTeamMembership.last_activity_at'
db
.
delete_column
(
'teams_courseteammembership'
,
'last_activity_at'
)
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
'teams.courseteam'
:
{
'Meta'
:
{
'object_name'
:
'CourseTeam'
},
'country'
:
(
'django_countries.fields.CountryField'
,
[],
{
'max_length'
:
'2'
,
'blank'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'date_created'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'300'
}),
'discussion_topic_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'255'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'language'
:
(
'student.models.LanguageField'
,
[],
{
'max_length'
:
'16'
,
'blank'
:
'True'
}),
'last_activity_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'team_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'255'
}),
'topic_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'db_index'
:
'True'
,
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'users'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'db_index'
:
'True'
,
'related_name'
:
"'teams'"
,
'symmetrical'
:
'False'
,
'through'
:
"orm['teams.CourseTeamMembership']"
,
'to'
:
"orm['auth.User']"
})
},
'teams.courseteammembership'
:
{
'Meta'
:
{
'unique_together'
:
"(('user', 'team'),)"
,
'object_name'
:
'CourseTeamMembership'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'last_activity_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{}),
'team'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'membership'"
,
'to'
:
"orm['teams.CourseTeam']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
}
}
complete_apps
=
[
'teams'
]
lms/djangoapps/teams/models.py
View file @
ce8f3112
"""Django models related to teams functionality."""
"""Django models related to teams functionality."""
from
uuid
import
uuid4
from
uuid
import
uuid4
import
pytz
from
datetime
import
datetime
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.db
import
models
from
django.db
import
models
...
@@ -23,13 +25,13 @@ class CourseTeam(models.Model):
...
@@ -23,13 +25,13 @@ class CourseTeam(models.Model):
course_id
=
CourseKeyField
(
max_length
=
255
,
db_index
=
True
)
course_id
=
CourseKeyField
(
max_length
=
255
,
db_index
=
True
)
topic_id
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
,
blank
=
True
)
topic_id
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
,
blank
=
True
)
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
# last_activity is computed through a query
description
=
models
.
CharField
(
max_length
=
300
)
description
=
models
.
CharField
(
max_length
=
300
)
country
=
CountryField
(
blank
=
True
)
country
=
CountryField
(
blank
=
True
)
language
=
LanguageField
(
language
=
LanguageField
(
blank
=
True
,
blank
=
True
,
help_text
=
ugettext_lazy
(
"Optional language the team uses as ISO 639-1 code."
),
help_text
=
ugettext_lazy
(
"Optional language the team uses as ISO 639-1 code."
),
)
)
last_activity_at
=
models
.
DateTimeField
()
users
=
models
.
ManyToManyField
(
User
,
db_index
=
True
,
related_name
=
'teams'
,
through
=
'CourseTeamMembership'
)
users
=
models
.
ManyToManyField
(
User
,
db_index
=
True
,
related_name
=
'teams'
,
through
=
'CourseTeamMembership'
)
@classmethod
@classmethod
...
@@ -62,6 +64,7 @@ class CourseTeam(models.Model):
...
@@ -62,6 +64,7 @@ class CourseTeam(models.Model):
description
=
description
,
description
=
description
,
country
=
country
if
country
else
''
,
country
=
country
if
country
else
''
,
language
=
language
if
language
else
''
,
language
=
language
if
language
else
''
,
last_activity_at
=
datetime
.
utcnow
()
.
replace
(
tzinfo
=
pytz
.
utc
)
)
)
return
course_team
return
course_team
...
@@ -88,6 +91,14 @@ class CourseTeamMembership(models.Model):
...
@@ -88,6 +91,14 @@ class CourseTeamMembership(models.Model):
user
=
models
.
ForeignKey
(
User
)
user
=
models
.
ForeignKey
(
User
)
team
=
models
.
ForeignKey
(
CourseTeam
,
related_name
=
'membership'
)
team
=
models
.
ForeignKey
(
CourseTeam
,
related_name
=
'membership'
)
date_joined
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_joined
=
models
.
DateTimeField
(
auto_now_add
=
True
)
last_activity_at
=
models
.
DateTimeField
()
def
save
(
self
,
*
args
,
**
kwargs
):
""" Customize save method to set the last_activity_at if it does not currently exist. """
if
not
self
.
last_activity_at
:
self
.
last_activity_at
=
datetime
.
utcnow
()
.
replace
(
tzinfo
=
pytz
.
utc
)
super
(
CourseTeamMembership
,
self
)
.
save
(
*
args
,
**
kwargs
)
@classmethod
@classmethod
def
get_memberships
(
cls
,
username
=
None
,
course_ids
=
None
,
team_id
=
None
):
def
get_memberships
(
cls
,
username
=
None
,
course_ids
=
None
,
team_id
=
None
):
...
...
lms/djangoapps/teams/serializers.py
View file @
ce8f3112
...
@@ -58,9 +58,10 @@ class CourseTeamSerializer(serializers.ModelSerializer):
...
@@ -58,9 +58,10 @@ class CourseTeamSerializer(serializers.ModelSerializer):
"description"
,
"description"
,
"country"
,
"country"
,
"language"
,
"language"
,
"last_activity_at"
,
"membership"
,
"membership"
,
)
)
read_only_fields
=
(
"course_id"
,
"date_created"
,
"discussion_topic_id"
)
read_only_fields
=
(
"course_id"
,
"date_created"
,
"discussion_topic_id"
,
"last_activity_at"
)
class
CourseTeamCreationSerializer
(
serializers
.
ModelSerializer
):
class
CourseTeamCreationSerializer
(
serializers
.
ModelSerializer
):
...
@@ -118,8 +119,8 @@ class MembershipSerializer(serializers.ModelSerializer):
...
@@ -118,8 +119,8 @@ class MembershipSerializer(serializers.ModelSerializer):
class
Meta
(
object
):
class
Meta
(
object
):
"""Defines meta information for the ModelSerializer."""
"""Defines meta information for the ModelSerializer."""
model
=
CourseTeamMembership
model
=
CourseTeamMembership
fields
=
(
"user"
,
"team"
,
"date_joined"
)
fields
=
(
"user"
,
"team"
,
"date_joined"
,
"last_activity_at"
)
read_only_fields
=
(
"date_joined"
,)
read_only_fields
=
(
"date_joined"
,
"last_activity_at"
)
class
PaginatedMembershipSerializer
(
PaginationSerializer
):
class
PaginatedMembershipSerializer
(
PaginationSerializer
):
...
...
lms/djangoapps/teams/tests/factories.py
View file @
ce8f3112
"""Factories for testing the Teams API."""
"""Factories for testing the Teams API."""
import
pytz
from
datetime
import
datetime
from
uuid
import
uuid4
from
uuid
import
uuid4
import
factory
import
factory
...
@@ -8,6 +10,9 @@ from factory.django import DjangoModelFactory
...
@@ -8,6 +10,9 @@ from factory.django import DjangoModelFactory
from
..models
import
CourseTeam
,
CourseTeamMembership
from
..models
import
CourseTeam
,
CourseTeamMembership
LAST_ACTIVITY_AT
=
datetime
(
2015
,
8
,
15
,
0
,
0
,
0
,
tzinfo
=
pytz
.
utc
)
class
CourseTeamFactory
(
DjangoModelFactory
):
class
CourseTeamFactory
(
DjangoModelFactory
):
"""Factory for CourseTeams.
"""Factory for CourseTeams.
...
@@ -20,8 +25,10 @@ class CourseTeamFactory(DjangoModelFactory):
...
@@ -20,8 +25,10 @@ class CourseTeamFactory(DjangoModelFactory):
discussion_topic_id
=
factory
.
LazyAttribute
(
lambda
a
:
uuid4
()
.
hex
)
discussion_topic_id
=
factory
.
LazyAttribute
(
lambda
a
:
uuid4
()
.
hex
)
name
=
"Awesome Team"
name
=
"Awesome Team"
description
=
"A simple description"
description
=
"A simple description"
last_activity_at
=
LAST_ACTIVITY_AT
class
CourseTeamMembershipFactory
(
DjangoModelFactory
):
class
CourseTeamMembershipFactory
(
DjangoModelFactory
):
"""Factory for CourseTeamMemberships."""
"""Factory for CourseTeamMemberships."""
FACTORY_FOR
=
CourseTeamMembership
FACTORY_FOR
=
CourseTeamMembership
last_activity_at
=
LAST_ACTIVITY_AT
lms/djangoapps/teams/tests/test_models.py
View file @
ce8f3112
...
@@ -29,9 +29,23 @@ class TeamMembershipTest(SharedModuleStoreTestCase):
...
@@ -29,9 +29,23 @@ class TeamMembershipTest(SharedModuleStoreTestCase):
self
.
team1
=
CourseTeamFactory
(
course_id
=
COURSE_KEY1
,
team_id
=
'team1'
)
self
.
team1
=
CourseTeamFactory
(
course_id
=
COURSE_KEY1
,
team_id
=
'team1'
)
self
.
team2
=
CourseTeamFactory
(
course_id
=
COURSE_KEY2
,
team_id
=
'team2'
)
self
.
team2
=
CourseTeamFactory
(
course_id
=
COURSE_KEY2
,
team_id
=
'team2'
)
self
.
team_membership11
=
CourseTeamMembershipFactory
(
user
=
self
.
user1
,
team
=
self
.
team1
)
self
.
team_membership11
=
CourseTeamMembership
(
user
=
self
.
user1
,
team
=
self
.
team1
)
self
.
team_membership12
=
CourseTeamMembershipFactory
(
user
=
self
.
user2
,
team
=
self
.
team1
)
self
.
team_membership11
.
save
()
self
.
team_membership21
=
CourseTeamMembershipFactory
(
user
=
self
.
user1
,
team
=
self
.
team2
)
self
.
team_membership12
=
CourseTeamMembership
(
user
=
self
.
user2
,
team
=
self
.
team1
)
self
.
team_membership12
.
save
()
self
.
team_membership21
=
CourseTeamMembership
(
user
=
self
.
user1
,
team
=
self
.
team2
)
self
.
team_membership21
.
save
()
def
test_membership_last_activity_set
(
self
):
current_last_activity
=
self
.
team_membership11
.
last_activity_at
# Assert that the first save in the setUp sets a value.
self
.
assertIsNotNone
(
current_last_activity
)
self
.
team_membership11
.
save
()
# Verify that we only change the last activity_at when it doesn't
# already exist.
self
.
assertEqual
(
self
.
team_membership11
.
last_activity_at
,
current_last_activity
)
@ddt.data
(
@ddt.data
(
(
None
,
None
,
None
,
3
),
(
None
,
None
,
None
,
3
),
...
...
lms/djangoapps/teams/tests/test_views.py
View file @
ce8f3112
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
"""Tests for the teams API at the HTTP request level."""
"""Tests for the teams API at the HTTP request level."""
import
json
import
json
import
pytz
from
datetime
import
datetime
from
dateutil
import
parser
import
ddt
import
ddt
...
@@ -13,7 +16,7 @@ from courseware.tests.factories import StaffFactory
...
@@ -13,7 +16,7 @@ from courseware.tests.factories import StaffFactory
from
student.tests.factories
import
UserFactory
,
AdminFactory
,
CourseEnrollmentFactory
from
student.tests.factories
import
UserFactory
,
AdminFactory
,
CourseEnrollmentFactory
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
.factories
import
CourseTeamFactory
from
.factories
import
CourseTeamFactory
,
LAST_ACTIVITY_AT
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
from
django_comment_common.models
import
Role
,
FORUM_ROLE_COMMUNITY_TA
from
django_comment_common.models
import
Role
,
FORUM_ROLE_COMMUNITY_TA
...
@@ -540,6 +543,13 @@ class TestCreateTeamAPI(TeamAPITestCase):
...
@@ -540,6 +543,13 @@ class TestCreateTeamAPI(TeamAPITestCase):
team_membership
=
team
[
'membership'
]
team_membership
=
team
[
'membership'
]
del
team
[
'membership'
]
del
team
[
'membership'
]
# verify that it's been set to a time today.
self
.
assertEqual
(
parser
.
parse
(
team
[
'last_activity_at'
])
.
date
(),
datetime
.
utcnow
()
.
replace
(
tzinfo
=
pytz
.
utc
)
.
date
()
)
del
team
[
'last_activity_at'
]
# Verify that the creating user gets added to the team.
# Verify that the creating user gets added to the team.
self
.
assertEqual
(
len
(
team_membership
),
1
)
self
.
assertEqual
(
len
(
team_membership
),
1
)
member
=
team_membership
[
0
][
'user'
]
member
=
team_membership
[
0
][
'user'
]
...
@@ -587,6 +597,7 @@ class TestDetailTeamAPI(TeamAPITestCase):
...
@@ -587,6 +597,7 @@ class TestDetailTeamAPI(TeamAPITestCase):
if
status
==
200
:
if
status
==
200
:
self
.
assertEqual
(
team
[
'description'
],
self
.
test_team_1
.
description
)
self
.
assertEqual
(
team
[
'description'
],
self
.
test_team_1
.
description
)
self
.
assertEqual
(
team
[
'discussion_topic_id'
],
self
.
test_team_1
.
discussion_topic_id
)
self
.
assertEqual
(
team
[
'discussion_topic_id'
],
self
.
test_team_1
.
discussion_topic_id
)
self
.
assertEqual
(
parser
.
parse
(
team
[
'last_activity_at'
]),
LAST_ACTIVITY_AT
)
def
test_does_not_exist
(
self
):
def
test_does_not_exist
(
self
):
self
.
get_team_detail
(
'no_such_team'
,
404
)
self
.
get_team_detail
(
'no_such_team'
,
404
)
...
...
lms/djangoapps/teams/views.py
View file @
ce8f3112
...
@@ -221,6 +221,9 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -221,6 +221,9 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
* language: Optionally specifies which language the team is
* language: Optionally specifies which language the team is
associated with.
associated with.
* last_activity_at: The date of the last activity of any team member
within the team.
* membership: A list of the users that are members of the team.
* membership: A list of the users that are members of the team.
See membership endpoint for more detail.
See membership endpoint for more detail.
...
@@ -449,6 +452,9 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
...
@@ -449,6 +452,9 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
* membership: A list of the users that are members of the team. See
* membership: A list of the users that are members of the team. See
membership endpoint for more detail.
membership endpoint for more detail.
* last_activity_at: The date of the last activity of any team member
within the team.
For all text fields, clients rendering the values should take care
For all text fields, clients rendering the values should take care
to HTML escape them to avoid script injections, as the data is
to HTML escape them to avoid script injections, as the data is
stored exactly as specified. The intention is that plain text is
stored exactly as specified. The intention is that plain text is
...
@@ -740,6 +746,9 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -740,6 +746,9 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
* date_joined: The date and time the membership was created.
* date_joined: The date and time the membership was created.
* last_activity_at: The date of the last activity of the user
within the team.
For all text fields, clients rendering the values should take care
For all text fields, clients rendering the values should take care
to HTML escape them to avoid script injections, as the data is
to HTML escape them to avoid script injections, as the data is
stored exactly as specified. The intention is that plain text is
stored exactly as specified. The intention is that plain text is
...
@@ -942,6 +951,9 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -942,6 +951,9 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
* date_joined: The date and time the membership was created.
* date_joined: The date and time the membership was created.
* last_activity_at: The date of the last activity of any team member
within the team.
For all text fields, clients rendering the values should take care
For all text fields, clients rendering the values should take care
to HTML escape them to avoid script injections, as the data is
to HTML escape them to avoid script injections, as the data is
stored exactly as specified. The intention is that plain text is
stored exactly as specified. The intention is that plain text is
...
...
Write
Preview
Markdown
is supported
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