devilry.apps.core.models — Devilry core datastructure

../_images/devilry.core.models.1.png ../_images/devilry.core.models.2.png

(edit the images umldiagram1 and umldiagram2 using yuml.me)

Functions and attributes

devilry.apps.core.models.model_utils.pathsep

Path separator used by node-paths. The value is '.', and it must not be changed.

devilry.apps.core.models.model_utils.splitpath(path, expected_len=0)

Split the path on pathsep and return the resulting list. Example:

>>> splitpath('uio.ifi.matnat')
['uio', 'ifi', 'matnat']
>>> splitpath('uio.ifi.matnat', expected_len=2)
Traceback (most recent call last):
...
ValueError: Path must have exactly 2 parts
Parameters:expected_len – Expected length of the resulting list. If the resulting list is not exactly the given length, ValueError is raised. If expected_len is 0 (default), no checking is done.

BaseNode

class devilry.apps.core.models.BaseNode

Bases: devilry.apps.core.models.save_interface.SaveInterface

The base class of the Devilry hierarchy. Implements basic functionality used by the other Node classes. This is an abstract datamodel, so it is never used directly.

short_name

A django.db.models.SlugField with max 20 characters. Only numbers, letters, ‘_’ and ‘-‘.

long_name

A django.db.models.CharField with max 100 characters. Gives a longer description than short_name.

AbstractIsAdmin

class devilry.apps.core.models.AbstractIsAdmin

Bases: object

Deprecated class - needs to clear migrations before this can be removed.

AbstractIsExaminer

class devilry.apps.core.models.AbstractIsExaminer

Bases: object

Abstract class implemented by all classes where it is natural to need to check if a user is examiner.

classmethod q_published(old=True, active=True)

Return a django.models.Q object which matches all items of this type where Assignment.publishing_time is in the past.

Parameters:
classmethod q_is_examiner(user_obj)

Return a django.models.Q object which matches items where the given user is examiner.

classmethod where_is_examiner(user_obj)

Get all items of this type where the given user_obj is examiner on one of the assignment groups.

Parameters:user_obj – A User object.
Return type:QuerySet
classmethod published_where_is_examiner(user_obj, old=True, active=True)

Get all published items of this type where the given user_obj is examiner on one of the assignment groups. Combines q_is_examiner() and q_published().

Parameters:
Returns:

A django.db.models.QuerySet with duplicate assignments eliminated.

classmethod active_where_is_examiner(user_obj)

Shortcut for published_where_is_examiner() with old=False.

classmethod old_where_is_examiner(user_obj)

Shortcut for published_where_is_examiner() with active=False.

Subject

A subject is a course, seminar, class or something else being given regularly. A subject is further divided into periods.

class devilry.apps.core.models.Subject(*args, **kwargs)

Bases: django.db.models.base.Model, devilry.apps.core.models.basenode.BaseNode, devilry.apps.core.models.abstract_is_examiner.AbstractIsExaminer, devilry.apps.core.models.abstract_is_candidate.AbstractIsCandidate, devilry.apps.core.models.model_utils.Etag

short_name

A django.db.models.SlugField with max 20 characters. Only numbers, letters, ‘_’ and ‘-‘. Unlike all other children of BaseNode, Subject.short_name is unique. This is mainly to avoid the overhead of having to recurse all the way to the top of the node hierarchy for every unique path.

periods

A set of periods for this subject.

etag

A DateTimeField containing the etag for this object.

get_path()

Only returns short_name for subject since it is guaranteed to be unique.

last_active_period

Get the last active devilry.apps.core.models.Period.

Only works if the queryset used to fetch the Subject is uses SubjectQuerySet.prefetch_active_periodobjects()

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Period

A Period is a limited period of time, like spring 2009, week 34 2010 or even a single day.

class devilry.apps.core.models.Period(*args, **kwargs)

Bases: django.db.models.base.Model, devilry.apps.core.models.basenode.BaseNode, devilry.apps.core.models.abstract_is_examiner.AbstractIsExaminer, devilry.apps.core.models.abstract_is_candidate.AbstractIsCandidate, devilry.apps.core.models.model_utils.Etag

A Period represents a period of time, for example a half-year term at a university.

parentnode

A django.db.models.ForeignKey that points to the parent node, which is always a Subject.

start_time

A django.db.models.DateTimeField representing the starting time of the period.

end_time

A django.db.models.DateTimeField representing the ending time of the period.

admins

A django.db.models.ManyToManyField that holds all the admins of the node.

assignments

A Django RelatedManager of assignments for this period.

relatedexaminer_set

A Django RelatedManager of RelatedExaminers for this period.

relatedstudent_set

A Django RelatedManager of RelatedStudents for this period.

etag

A DateTimeField containing the etag for this object.

classmethod q_published(old=True, active=True)

Return a django.models.Q object which matches all items of this type where Assignment.publishing_time is in the past.

Parameters:
clean(*args, **kwargs)

Validate the period.

Always call this before save()! Read about validation here: http://docs.djangoproject.com/en/dev/ref/models/instances/#id1

Raises ValidationError if start_time is after end_time.

is_active()

Returns true if the period is active

classmethod q_is_active()

Get a django.db.models.Q object that matches all active periods (periods where start_time is in the past, and end_time is in the future).

Example:

activeperiods = Period.objects.filter(Period.q_is_active())
classmethod q_is_examiner(user_obj)

Return a django.models.Q object which matches items where the given user is examiner.

is_empty()

Returns True if this Period does not contain any assignments.

subject

More readable alternative to self.parentnode.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Assignment

Represents one assignment within a given Period in a given Subject. Each assignment contains one AssignmentGroup for each student or group of students permitted to submit deliveries.

We have three main classifications of assignments:

  1. A old assignment is a assignment where Period.end_time is in the past.
  2. A published assignment is a assignment where publishing_time is in the past.
  3. A active assignment is a assignment where publishing_time is in the past and current time is before Period.end_time.
class devilry.apps.core.models.Assignment(*args, **kwargs)

Bases: django.db.models.base.Model, devilry.apps.core.models.basenode.BaseNode, devilry.apps.core.models.abstract_is_examiner.AbstractIsExaminer, devilry.apps.core.models.abstract_is_candidate.AbstractIsCandidate

Data model for an assignment.

gradeform_setup_json

A django.db.models.TextField for the json representing a blank gradeform used for this ‘Assignment

parentnode

A django.db.models.ForeignKey that points to the parent node, which is always a Period.

publishing_time

A django.db.models.DateTimeField representing the publishing time of the assignment.

admins

A django.db.models.ManyToManyField that holds all the admins of the Node.

assignmentgroups

A set of assignmentgroups for this assignment

scale_points_percent

Percent to scale points on this assignment by for period overviews. The default is 100, which means no change to the points.

delivery_types

An integer identifying the type of deliveries allowed. Possible values:

0
Electronic deliveries using Devilry
1
Non-electronic deliveries, or deliveries made through another electronic system.
2
An alias/link to a delivery made in another Period.
deadline_handling

An integer identifying how deadlines are handled.

0
Soft deadlines. Deliveries can be added until groups are closed.
1
Hard deadlines. Deliveries can not be added after the deadline has expired.
first_deadline

A DateTimeField containing an optional first deadline for this assignment. This is metadata that the UI can use where it is natural.

max_points

An IntegerField that contains the maximum number of points possible to achieve on this assignment. This field may be None, and it is normally set by the grading system plugin.

DO NOT UPDATE MANUALLY. You can safely set an initial value for this manually when you create a new assignment, but when you update this field, do so using set_max_points().

passing_grade_min_points

An IntegerField that contains the minimum number of points required to achive a passing grade on this assignment. This means that any feedback with more this number of points or more is considered a passing grade.

WARNING: Changing this does not have any effect on existing feedback. To actually change existing feedback, you would have to update all feedback on the assignment, effectively creating new StaticFeedbacks from the latest published FeedbackDrafts for each AssignmentGroup.

grading_system_plugin_id

A CharField containing the ID of the grading system plugin this assignment uses.

students_can_create_groups

BooleanField specifying if students can join/leave groups on their own.

If this is True students should be allowed to join/leave groups. If students_can_not_create_groups_after is specified, this students can not create groups after students_can_not_create_groups_after even if this is True.ar 16 2017, 17:45 : This delivery was corrected, and given:

This does not in any way affect an admins ability to organize students in groups manually.

students_can_not_create_groups_after

Students can not create project groups after this time. Ignored if students_can_create_groups is False.

DateTimeField that defaults to None (null).

feedback_workflow

The feedback workflow used on the assignment. A feedback workflow defines how examiners and administrators work together to make feedback available to students.

Introduced in issue 765.

deprecated_field_anonymous

Deprecated anonymous field. Will be removed in 3.1.

ANONYMIZATIONMODE_OFF = 'off'

Constant for the anonymizationmode “off” choice.

ANONYMIZATIONMODE_SEMI_ANONYMOUS = 'semi_anonymous'

Constant for the anonymizationmode “semi_anonymous” choice.

ANONYMIZATIONMODE_FULLY_ANONYMOUS = 'fully_anonymous'

Constant for the anonymizationmode “fully_anonymous” choice.

ANONYMIZATIONMODE_CHOICES = [('off', u'OFF. Normal assignment where semester and course admins can see everything, and examiners and students can see each others names and contact information.'), ('semi_anonymous', u'SEMI ANONYMOUS. Students and examiners can not see information about each other. Comments added by course admins are not anonymized. Semester admins do not have access to the assignment in the admin UI. Course admins have the same permissions as for "OFF".'), ('fully_anonymous', u'FULLY ANONYMIZED. Intended for exams where course admins are examiners. Students and examiners can not see information about each other. Hidden from semester admins. Course admins can not view grading details. Only departmentadmins and superusers can change this back to another "anoymization mode" when feedback has been added to the assignment. Course admins can not edit examiners after the first feedback is provided.')]

Choices for anonymizationmode.

ANONYMIZATIONMODE_CHOICES_DICT = {'fully_anonymous': u'FULLY ANONYMIZED. Intended for exams where course admins are examiners. Students and examiners can not see information about each other. Hidden from semester admins. Course admins can not view grading details. Only departmentadmins and superusers can change this back to another "anoymization mode" when feedback has been added to the assignment. Course admins can not edit examiners after the first feedback is provided.', 'off': u'OFF. Normal assignment where semester and course admins can see everything, and examiners and students can see each others names and contact information.', 'semi_anonymous': u'SEMI ANONYMOUS. Students and examiners can not see information about each other. Comments added by course admins are not anonymized. Semester admins do not have access to the assignment in the admin UI. Course admins have the same permissions as for "OFF".'}

Dictionary for getting the ANONYMIZATIONMODE_CHOICES descriptions

ANONYMIZATIONMODE_CHOICES_SHORT_LABEL_DICT = {'fully_anonymous': u'fully anonymized', 'off': u'off', 'semi_anonymous': u'semi anonymous'}

Dictionary mapping Assignment.anonymizationmode choices to short labels.

anonymizationmode

A choicefield that specifies how the assignment is anonymized (or not).

Choices:

  • "off": Normal assignment where semester and course admins can see everything, and examiners and students can see each others names and contact information.
  • "semi_anonymous": Students and examiners can not see information about each other. Semester admins can not view the assignment at all. Course admins have the same permissions as for "off".
  • "fully_anonymous": Students and examiners can not see information about each other. Course admins can not view results (or AssignmentGroup.id). Hidden from semester admins. Can not be changed unless you are member of a group with grouptype="departmentadmin" and has access to the assignment. Course admins can not edit examiners after the first feedback is provided.
POINTS_TO_GRADE_MAPPER_PASSED_FAILED = 'passed-failed'

The “passed-or-failed” value for points_to_grade_mapper. Zero points results in a failing grade, other points results in a passing grade.

POINTS_TO_GRADE_MAPPER_RAW_POINTS = 'raw-points'

The “raw-points” value for points_to_grade_mapper. The grade is <points>/<max-points>.

POINTS_TO_GRADE_MAPPER_CUSTOM_TABLE = 'custom-table'

The “custom-table” value for points_to_grade_mapper. For this choice, someone configures a mapping from point thresholds to grades using devilry.apps.core.models.PointRangeToGrade.

POINTS_TO_GRADE_MAPPER_CHOICES = [('passed-failed', u'Passed or failed'), ('raw-points', u'Points'), ('custom-table', u'Lookup in a table defined by you (A-F, and other grading systems)')]

Choices for points_to_grade_mapper

POINTS_TO_GRADE_MAPPER_CHOICES_DICT = {'custom-table': u'Lookup in a table defined by you (A-F, and other grading systems)', 'passed-failed': u'Passed or failed', 'raw-points': u'Points'}

Dictionary for getting the POINTS_TO_GRADE_MAPPER_CHOICES descriptions

points_to_grade_mapper

Points to grade mapper. Defines how we map points to a grade. Choices are:

GRADING_SYSTEM_PLUGIN_ID_CHOICES_DICT = {'devilry_gradingsystemplugin_approved': u'PASSED/FAILED. The examiner selects passed or failed.', 'devilry_gradingsystemplugin_points': u'POINTS. The examiner types in the number of points to award the student(s) for this assignment.'}

Dictionary for getting the GRADING_SYSTEM_PLUGIN_ID_CHOICES descriptions

grading_system_plugin_id

Grading system plugin ID. Defines how examiners grade the students.

is_anonymous

Returns True if anonymizationmode != "off".

is_semi_anonymous

Returns True if anonymizationmode == "semi_anonymous".

is_fully_anonymous

Returns True if anonymizationmode == "semi_anonymous".

publishing_time_is_in_future

Returns True if publishing_time is in the future.

is_published

Returns True if publishing_time is in the past.

students_can_create_groups_now

Returns True if students_can_create_groups is True, and students_can_not_create_groups_after is in the future or None.

students_must_be_anonymized_for_devilryrole(devilryrole)

Check if students must be anonymized for the given devilryrole.

Parameters:devilryrole

Must be one of "student", "examiner", "periodadmin", "subjectadmin" or "departmentadmin". This is used to determine if candidates needs to be anonymized or not using the following rules:

  • If devilryrole is "student", candidates do not need to be anonymized even if the assignment is anonymous.
  • If devilryrole is "examiner", candidates need to be anonymized if the assignment is anonymous.
  • If devilryrole is "periodadmin", and the assignment is anonymous, we raise ValueError. This is because it is a bug for periodadmins to get access to any anonymous assignments.
  • If devilryrole is "subjectadmin", candidates need to be anonymized if the assignment is anonymized with anonymizationmode="fully_anonymous".
  • If devilryrole is "departmentadmin", candidates do not need to be anonymized even if the assignment is anonymous.
Raises:ValueError – If the assignment is anonymous and devilryrole == "periodadmin" (explained above).
Returns:True if the candidates must be anonymized for the given role.
Return type:bool
examiners_must_be_anonymized_for_devilryrole(devilryrole)

Check if examiners must be anonymized for the given devilryrole.

Parameters:devilryrole

Must be one of "student", "examiner", "periodadmin", "subjectadmin" or "departmentadmin". This is used to determine if examiners needs to be anonymized or not using the following rules:

  • If devilryrole is "student", examiners need to be anonymized if the assignment is anonymous.
  • If devilryrole is "examiner", examiners do not need to be anonymized even if the assignment is anonymous.
  • If devilryrole is "periodadmin", and the assignment is anonymous, we raise ValueError. This is because it is a bug for periodadmins to get access to any anonymous assignments.
  • If devilryrole is "subjectadmin", examiners need to be anonymized if the assignment is anonymized with anonymizationmode="fully_anonymous".
Raises:ValueError – If the assignment is anonymous and devilryrole == "periodadmin" (explained above).
Returns:True if the examiners must be anonymized for the given role.
Return type:bool
feedback_workflow_allows_shared_feedback_drafts()

Return True if the feedback_workflow allows examiners to access each others feedback drafts.

feedback_workflow_allows_examiners_publish_feedback()

Return True if the feedback_workflow allows examiners to publish feedback.

is_electronic()

Returns True if deliverytypes is 0 (electric).

New in version 1.4.0.

is_nonelectronic()

Returns True if deliverytypes is 1 (non-electric).

New in version 1.4.0.

set_max_points(max_points)

Sets max_points, and invalidates any PointToGradeMap configured for this assignment if the new value for max_points differs from the old one.

Invalidating the PointToGradeMap ensures that the course admin has to re-evaluate the grade to point mapping when they change max_points.

NOTE: This saves the PointToGradeMap, but not the assignment.

get_gradingsystem_plugin_api()

Shortcut for:

devilry.devilry_gradingsystem.pluginregistry.gradingsystempluginregistry.get(
    self.grading_system_plugin_id)(self)

See: devilry.devilry_gradingsystem.pluginregistry.GradingSystemPluginRegistry.get().

has_valid_grading_setup()

Checks if this assignment is configured correctly for grading.

setup_grading(grading_system_plugin_id, points_to_grade_mapper, passing_grade_min_points=None, max_points=None)

Setup all of the simple parts of the grading system:

Does not setup:

  • Grading system plugin specific configuration.
  • A PointToGradeMap.
get_point_to_grade_map()

Get the PointToGradeMap for this assignment, or None if there is no PointToGradeMap for this assignment.

get_points_to_grade_map_as_cached_dict()

Uses get_point_to_grade_map() to get the grade to points map object, then transforms it into an OrderedDict using devilry.apps.core.models.PointToGradeMap.as_flat_dict().

The results are cached on this Assignment object, so multiple calls to this method on an Assignment object does not require any extra performance cost.

points_is_passing_grade(points)

Checks if the given points represents a passing grade.

points_to_grade(points)

Convert the given points into a grade.

WARNING: This will not work if has_valid_grading_setup() is not True.

classmethod q_published(old=True, active=True)

Return a django.models.Q object which matches all items of this type where Assignment.publishing_time is in the past.

Parameters:
classmethod q_is_examiner(user_obj)

Return a django.models.Q object which matches items where the given user is examiner.

clean()

Validate the assignment.

Always call this before save()! Read about validation here: http://docs.djangoproject.com/en/dev/ref/models/instances/#id1

Raises ValidationError if publishing_time is not between Period.start_time and Period.end_time.

is_empty()

Returns True if this Assignment does not contain any deliveries.

is_active()

Returns True if this assignment is published, and the period has not ended yet.

get_groups_with_passing_grade(sourceassignment)

Get devilry.apps.core.models.assignment_group.AssignmentGroup`s for the ``sourceassignment` where the last devilry.devilry_group.models.FeedbackSet has a passing grade.

Parameters:sourceassignment – A Assignment to copy groups from.
Returns
QuerySet: A devilry.apps.core.models.assignment_group.AssignmentGroup queryset.
copy_groups_from_another_assignment(sourceassignment, passing_grade_only=False)

Copy all AssignmentGroup objects from another assignment.

Copies:

  • The name of the group.
create_groups_from_relatedstudents_on_period()

Create devilry.apps.core.models.AssignmentGroup objects for all devilry.apps.core.models.RelatedStudent objects on the period owning this assignment.

Creates one AssignmentGroup for each RelatedStudent, with a single Candidate in each AssignmentGroup.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Examiner

class devilry.apps.core.models.Examiner(*args, **kwargs)

Bases: django.db.models.base.Model, devilry.apps.core.models.abstract_is_admin.AbstractIsAdmin

assignmentgroup

The AssignmentGroup where this groups belongs.

user

A foreign key to a User.

Candidate

class devilry.apps.core.models.Candidate(*args, **kwargs)

Bases: django.db.models.base.Model

A student within an AssignmentGroup.

A candidate is a many-to-many between devilry.apps.core.models.AssignmentGroup and a user.

AssignmentGroup

class devilry.apps.core.models.AssignmentGroup(*args, **kwargs)

Bases: django.db.models.base.Model, devilry.apps.core.models.abstract_is_admin.AbstractIsAdmin, devilry.apps.core.models.abstract_is_examiner.AbstractIsExaminer, devilry.apps.core.models.model_utils.Etag

Represents a student or a group of students.

parentnode

A django.db.models.ForeignKey that points to the parent node, which is always an Assignment.

name

An optional name for the group.

candidates

A django RelatedManager that holds the candidates on this group.

examiners

A django.db.models.ManyToManyField that holds the examiner(s) that are to correct and grade the assignment.

is_open

A django.db.models.BooleanField that tells you if the group can add deliveries or not.

deadlines

A django RelatedManager that holds the deadlines on this group.

tags

A django RelatedManager that holds the tags on this group.

last_deadline

The last devilry.apps.core.models.Deadline for this assignmentgroup.

etag

A DateTimeField containing the etag for this object.

delivery_status

A CharField containing the status of the group. Valid status values:

  • “no-deadlines”
  • “corrected”
  • “closed-without-feedback”
  • “waiting-for-something”
cached_data

A Django RelatedManager of cached_data for this AssignmentGroup.

feedbackset

A Django RelatedManager devilry.apps.core.models.FeedbackSet for this AssignmentGroup

Note

Postgres triggers create a devilry.apps.core.models.FeedbackSet on INSERT

batchoperation

Foreignkey to ievv_opensource.ievv_batchframework.models.BatchOperation. When we perform batch operations on the assignmentgroup, this is used to reference the operation. Batch operations include bulk-create - we use the BatchOperation object to enable us to recursively batch create AssignmentGroup, Candidate and FeedbackSet in a very efficient batch operation with a fixed set of database queries.

copied_from

If this group was copied from another group, this will be set. This can safely be set to None at any time since it is only used to make it possible to bulk copy huge amounts of groups efficiently.

created_datetime

The time when this group was created.

save(*args, **kwargs)
Parameters:
  • update_delivery_status – Update the delivery_status? This is a somewhat expensive operation, so we provide the option to avoid it if needed. Defaults to True.
  • autocreate_first_deadline_for_nonelectronic – Autocreate the first deadline if non-electronic assignment? Defaults to True.
classmethod q_is_candidate(user_obj)

Returns a django.models.Q object matching AssignmentGroups where the given student is candidate.

classmethod where_is_candidate(user_obj)

Returns a QuerySet matching all AssignmentGroups where the given user is student.

Parameters:user_obj – A User object.
Return type:QuerySet
classmethod published_where_is_candidate(user_obj, old=True, active=True)

Returns a QuerySet matching all published assignment groups where the given user is student.

Parameters:user_obj – A User object.
Return type:QuerySet
classmethod active_where_is_candidate(user_obj)

Returns a QuerySet matching all active assignment groups where the given user is student.

Parameters:user_obj – A User object.
Return type:QuerySet
classmethod old_where_is_candidate(user_obj)

Returns a QuerySet matching all old assignment groups where the given user is student.

Parameters:user_obj – A User object.
Return type:QuerySet
classmethod q_published(old=True, active=True)

Return a django.models.Q object which matches all items of this type where Assignment.publishing_time is in the past.

Parameters:
classmethod q_is_examiner(user_obj)

Return a django.models.Q object which matches items where the given user is examiner.

should_ask_if_examiner_want_to_give_another_chance

True if the current state of the group is such that the examiner should be asked if they want to give them another chance.

True if corrected with failing grade or closed without feedback.

missing_expected_delivery

Return True if the group has no deliveries, and we are expecting them to have made at least one delivery on the last deadline.

subject

Shortcut for parentnode.parentnode.parentnode.

period

Shortcut for parentnode.parentnode.

assignment

Alias for parentnode.

get_anonymous_displayname(assignment=None)

Get the anonymous displayname for this group.

Parameters:assignment – An optional devilry.apps.core.models.assignment.Assignment. if this is provided, we use this instead of looking up parentnode. This is essential for views that list many groups since it avoid extra database lookups.
short_displayname

A short displayname for the group. If the assignment is anonymous, we list the candidate IDs. If the group has a name, the name is used, else we fall back to a comma separated list of usernames. If the group has no name and no students, we use the ID.

get_long_displayname(assignment=None)

A long displayname for the group. If the assignment is anonymous, we list the candidate IDs.

If the assignment is not anonymous, we use a comma separated list of the displaynames (full names with fallback to shortname) of the students. If the group has a name, we use the groupname with the names of the students in parenthesis.

long_displayname

A long displayname for the group. If the assignment is anonymous, we list the candidate IDs.

If the assignment is not anonymous, we use a comma separated list of the displaynames (full names with fallback to shortname) of the students. If the group has a name, we use the groupname with the names of the students in parenthesis.

get_examiners(separator=u', ')

Get a string contaning the shortname of all examiners in the group separated by comma (',').

Parameters:separator – The unicode string used to separate candidates. Defaults to u', '.
is_examiner(user_obj)

Return True if user is examiner on this assignment group

can_delete(user_obj)

Check if the given user is permitted to delete this AssignmentGroup. A user is permitted to delete an object if the user is superadmin, or if the user is admin on the assignment (uses is_admin()). Only superusers are allowed to delete AssignmentGroups where AssignmentGroup.is_empty() returns False.

Note

This method can also be used to check if candidates can be removed from the group.

Returns:True if the user is permitted to delete this object.
is_empty()

Returns True if this AssignmentGroup does not contain any deliveries.

get_active_deadline()

Get the active Deadline.

This is always the last deadline on this group.

Returns:The latest deadline or None.
can_save(user_obj)

Check if the user has permission to save this AssignmentGroup.

can_add_deliveries()

Returns true if a student can add deliveries on this assignmentgroup

Both the assignmentgroups is_open attribute, and the periods start and end time is checked.

copy_all_except_candidates()

copy everything assignment group contains into a new AssignmentGroup, except candiates.

Returns:AssignmentGroup a new assignmentgroup
recalculate_delivery_numbers()

Query all successful deliveries on this AssignmentGroup, ordered by time_of_delivery ascending, and number them with the oldest delivery as number 1.

merge_into(target)

Merge this AssignmentGroup into target AssignmentGroup

  • Move all feedbacksets into target AssignmentGroup
  • Move in all candidates not already on the AssignmentGroup.
  • Move in all examiners not already on the AssignmentGroup.
  • Move in all tags not already on the AssignmentGroup.
  • delete this AssignmentGroup
Parameters:targetAssignmentGroup the assignment group that self will be merged into
Raises:ValueError if self and target AssignmentGroup is not part of same Assignment

Returns:

can_merge(target)

Checks whether we can merge into target :param target: AssignmentGroup target assignment group

Raises:ValidationError
set_all_target_feedbacksets_to_merge_type(target)

Set all FeedbackSet types to it’s corresponding merge type for the target group.

Parameters:targetAssignmentGroup the assignment group to add new feedbackset to.
create_new_first_attempt_for_target_group(target)

Create a new FeedbackSet with type first_attempt for target group.

Parameters:targetAssignmentGroup the assignment group to add new feedbackset to.
classmethod merge_groups(groups)

First group will be target assignment group, the rest of the groups in the list will be merged into target.

For further explanation see: How do we merge assignment groups? :param groups: list with AssignmentGroup

Raises:ValidationError if we are not able to merge groups
pop_candidate(candidate)

Pops a candidate off the assignment group. Copy this Assignment group and all inherent Feedbacksets and comments

Parameters:candidateCandidate
Raises:GroupPopNotCandiateError when candiate is not part of AssignmentGroup

Returns:

get_current_state()

Dumps the current state of this AssignmentGroup and all inherent models such as user.id of candidates and examiners, tags and feedbacksets into a dictionary.

Returns:dictonary with current state of assignmentGroup and all inherent models
get_status()

Get the status of the group. Calculated with this algorithm:

if ``delivery_status == 'waiting-for-something'``
    if assignment.delivery_types==NON_ELECTRONIC:
        "waiting-for-feedback"
    else
        if before deadline
            "waiting-for-deliveries"
        if after deadline:
            "waiting-for-feedback"
else
    delivery_status
published_grading_points

Get the grading_points from the last published devilry.devilry_group.models.FeedbackSet.

This means that this property returns the current public grade for the AssignmentGroup.

drafted_grading_points

Get the grading_points from the last devilry.devilry_group.models.FeedbackSet if the last feedbackset is not the same as the published feedbackset.

If the last published feedbackset is the same as the last feedbackset, this always returns None. This will also return None if the last feedbackset does not have a grade yet.

published_grade_is_passing_grade

Returns True if published_grading_points() is a passing grade.

has_unpublished_feedbackdraft

A group is considered to have an unpublished feedback draft if the following is true for the last feedbackset:

So this means that if this property returns True, the group is corrected, and ready be be published.

is_corrected

Returns True if the last feedbackset is published.

is_waiting_for_feedback

Groups waiting for feedback is all groups where the deadline of the last feedbackset (or Assignment.first_deadline and only one feedbackset) has expired, and the feedbackset does not have a grading_published_datetime.

is_waiting_for_deliveries

Groups waiting for deliveries is all groups where the deadline of the last feedbackset (or Assignment.first_deadline and only one feedbackset) has not expired, and the feedbackset does not have a grading_published_datetime.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

AssignmentGroupTag

class devilry.apps.core.models.AssignmentGroupTag(*args, **kwargs)

Bases: django.db.models.base.Model

An AssignmentGroup can be tagged with zero or more tags using this class.

assignment_group

The AssignmentGroup where this groups belongs.

tag

The tag. Max 20 characters. Can only contain a-z, A-Z, 0-9 and “_”.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned