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)[source]

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.abstract_is_admin.AbstractIsAdmin, 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

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

classmethod q_is_admin(user_obj)

Get a django.db.models.Q object matching all objects of this type where the given user is admin. The matched result is not guaranteed to contain unique items, so you should use distinct() on the queryset if this is required.

This must be implemented in all subclassed.

classmethod where_is_admin(user_obj, *related_fields)

Get all objects of this type where the given user is admin.

classmethod where_is_admin_or_superadmin(user_obj, *related_fields)

Get all objects of this type where the given user is admin, or all objects if the user is superadmin.

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 django.contrib.auth.models.User object.
Return type:QuerySet
classmethod published_where_is_examiner(user_obj, old=True, active=True)

Get all published <assignment-classifications>` 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:
  • user_objq_is_examiner().
  • oldq_published().
  • activeq_published().
Returns:

A django.db.models.query.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.

Node

A node at the top of the navigation tree. It is a generic element used to organize administrators. A Node can be organized below another Node, and it can only have one parent.

Let us say you use Devilry within two departments at Fantasy University; informatics and mathematics. The university has an administration, and each department have their own administration. You would end up with this node-hierarchy:

  • Fantasy University
    • Department of informatics
    • Department of mathematics
class devilry.apps.core.models.Node(*args, **kwargs)

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

This class is typically used to represent a hierarchy of institutions, faculties and departments.

parentnode

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

admins

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

child_nodes

A set of child_nodes of type Node for this node

subjects

A set of subjects for this node

etag

A DateTimeField containing the etag for this object.

iter_childnodes()

Recursively iterates over all child nodes, and their child nodes. For a list of direct child nodes, use atribute child_nodes instead.

clean(*args, **kwargs)

Validate the node, making sure it does not do something stupid.

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

Raises ValidationError if:

  • The node is it’s own parent.
  • The node is the child of itself or one of its childnodes.

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

parentnode

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

admins

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

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.

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 set of assignments for this period.

etag

A DateTimeField containing the etag for this object.

relatedstudents

A django.db.models.ForeignKey that points to the related students for this period.

relatedexaminers

A django.db.models.ForeignKey that points to the related examiners for this period.

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

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, devilry.apps.core.models.model_utils.Etag

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.

anonymous

A models.BooleanField specifying if the assignment should be anonymously for correcters.

admins

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

assignmentgroups

A set of assignmentgroups for this assignment

examiners_publish_feedbacks_directly

Should feedbacks published by examiners be made avalable to the students immediately? If not, an administrator have to publish feedbacks. See also Deadline.feedbacks_published.

etag

A DateTimeField containing the etag for this object.

update_candidates_identifer()

If the anonymous flag is changed, update the identifer on all the candidates on this assignment.

clean(*args, **kwargs)

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.

Candidate

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

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

assignment_group

The AssignmentGroup where this groups belongs.

student

A student (a foreign key to a User).

candidate_id

A optional candidate id. This can be anything as long as it is not more than 30 characters. When the assignment is anonymous, this is the “name” shown to examiners instead of the username of the student.

identifier
The candidate_id if this is a candidate on an anonymous assignment, and username if not.

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.

feedback

The last StaticFeedback (by save timestamp) on this assignmentgroup.

etag

A DateTimeField containing the etag for this object.

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 django.contrib.auth.models.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 django.contrib.auth.models.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 django.contrib.auth.models.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 django.contrib.auth.models.User object.
Return type:QuerySet
get_students()

Get a string containing all students in the group separated by comma and a space, like: superman, spiderman, batman.

WARNING: You should never use this method when the user is not an administrator. Use get_candidates() instead.

get_candidates()

Get a string containing all candiates in the group separated by comma and a space, like: superman, spiderman, batman for normal assignments, and something like: 321, 1533, 111 for anonymous assignments.

get_examiners()

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

is_examiner(user_obj)

Return True if user is examiner on this assignment group

get_active_deadline()

Get the active Deadline.

This is always the last deadline on this group.

Returns:The latest deadline.
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.

Deadline

Each AssignmentGroup have zero or more deadlines.

class devilry.apps.core.models.Deadline(*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.abstract_is_candidate.AbstractIsCandidate

A deadline on an AssignmentGroup. A deadline contains zero or more deliveries, the time of the deadline and an optional text.

assignment_group

The AssignmentGroup where the deadline is registered.

deadline

The deadline a DateTimeField.

text

A optional deadline text.

deliveries

A django RelatedManager that holds the deliveries on this group.

deliveries_available_before_deadline

Should deliveries on this deadline be available to examiners before the deadline expires? This is set by students.

feedbacks_published

If this boolean field is True, the student can see all StaticFeedback objects associated with this Deadline through a Delivery. See also Assignment.examiners_publish_feedbacks_directly.

clean(*args, **kwargs)

Validate the deadline.

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

Raises ValidationError if:

  • deadline is before Assignment.publishing_time.
  • deadline is not before Period.end_time.

Delivery

Examples

Simple example:

assignmentgroup = AssignmentGroup.objects.get(id=1)
assignmentgroup.deliveries.create(delivered_by=student1,
                                  successful=True)

More advanced example:

assignmentgroup = AssignmentGroup.objects.get(id=1)
delivery = assignmentgroup.deliveries.create(delivered_by=student1,
                                             successful=False)
delivery.add_file('test.py', ['print', 'hello world'])
delivery.add_file('test2.py', ['print "hi"'])
delivery.successful = True
delivery.save()

The input to add_file() will normally be a file-like object, but as shown above it can be anything you want.

Delivery API

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

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

A class representing a given delivery from an AssignmentGroup.

time_of_delivery

A django.db.models.DateTimeField that holds the date and time the Delivery was uploaded.

deadline

A django.db.models.ForeignKey pointing to the Deadline for this Delivery.

number

A django.db.models.fields.PositiveIntegerField with the delivery-number within this assignment-group. This number is automatically incremented within each assignmentgroup, starting from 1. Must be unique within the assignment-group. Automatic incrementation is used if number is None when calling save().

delivered_by

A django.db.models.ForeignKey pointing to the user that uploaded the Delivery

successful

A django.db.models.BooleanField telling whether or not the Delivery was successfully uploaded.

after_deadline

A django.db.models.BooleanField telling whether or not the Delivery was delived after deadline..

filemetas

A set of filemetas for this delivery.

feedbacks

A set of feedbacks on this delivery.

etag

A DateTimeField containing the etag for this object.

after_deadline

Compares the deadline and time of delivery. If time_of_delivery is greater than the deadline, return True.

classmethod q_is_candidate(user_obj)

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

add_file(filename, iterable_data)

Add a file to the delivery.

Parameters:
  • filename – A filename as defined in FileMeta.
  • iterable_data – A iterable yielding data that can be written to file using the write() method of a storage backend (byte strings).
save(*args, **kwargs)

Set number automatically to one greater than what is was last and add the delivery to the latest deadline (see AssignmentGroup.get_active_deadline()).

StaticFeedback

class devilry.apps.core.models.StaticFeedback(*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.abstract_is_candidate.AbstractIsCandidate

Represents a feedback for a Delivery.

Each delivery can have zero or more feedbacks. Each StaticFeedback object stores static data that an examiner has published on a delivery. StaticFeedback is created and edited in a grade+feedback editor in a grade plugin, and when an examiner choose to publish feedback, a static copy of the data he/she created in the grade+feedback editor is stored in a StaticFeedback.

Feedbacks are only visible to students when Deadline.feedbacks_published on the related deadline is True. Feedbacks are related to Deadlines through its delivery.

Students are presented with the last feedback on a delivery, however they can browse every StaticFeedback on their deliveries. This history is to protect the student from administrators or examiners that change published feedback to avoid that a student can make an issue out of a bad feedback.

NOTE: When a StaticFeedback is saved, the corresponding AssignmentGroup.feedback is updated to the newly created StaticFeedback.

rendered_view

The rendered HTML view.

saved_by

The django.contrib.auth.models.User that created the StaticFeedback.

save_timestamp

Date/time when this feedback was created.

delivery

A django.db.models.ForeignKey that points to the Delivery where this feedback belongs.

grade

The grade as a short string (max 12 chars).

points

The number of points (integer).

is_passing_grade

Boolean is passing grade?

classmethod q_is_candidate(user_obj)

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

classmethod q_is_examiner(user_obj)

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

FileMeta

class devilry.apps.core.models.FileMeta(*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.abstract_is_candidate.AbstractIsCandidate

Represents the metadata for a file belonging to a Delivery.

A file meta is just information about a single file, which is stored in a deliverystore. Use the deliverystore to manage the file stored in its physical location. Example:

filemeta = FileMeta.objects.get(pk=0)
if filemeta.deliverystore.exists(filemeta):
    filemeta.deliverystore.remove(filemeta)

# Write or read just as with the builtin open()
fobj = filemeta.deliverystore.write_open(filemeta)
fobj.write('Hello')
fobj.write('World')
fobj.close()
fobj = filemeta.deliverystore.read_open(filemeta)
print fobj.read()

See DeliveryStore for more details on deliverystores.

delivery

A django.db.models.ForeignKey that points to the Delivery of the given feedback.

filename

Name of the file.

size

Size of the file in bytes.

deliverystore

The current DeliveryStore. Class variable.