devilry_group — Devilry group models and views

The devilry_group module handles the delivery of assignments by students.

About the devilry group app

The devilry_group app uses a comment/event-based feedbackfeed system for delivering assignments and recieiving feedback on those deliveries.

  • The feedbackfeed gather all information about a an assignment in one place, and makes it easy for students, examiners and admins to communicate.
  • The feedbackfeed consists of one or more feedbacksets.
  • A feedbackset may or may not have a deadline and zero or more comments belonging to it.
  • Students, examiners and admins can write comments to the feedbackset.
  • If a student fails an assignment, and is given another chance, a new feedbackset is created with a new deadline.
  • All events show up in the feed in the order they happen, when a deadline is created, a comment is posted, a deadline ends and the status of the grading. You also have direct access to download the files delivered from the feedbackfeed.

What is a FeedbackSet?

The FeedbackSet has a foreignkey to an AssignmentGroup and groups all information about a specific deadline for the Assignment the AssignmentGroup is associated with. A new FeedbackSet is created for each deadline e.g. regarding new attempts if the student failed on the first delivery. See the model API below.

Datamodel API

exception devilry.devilry_group.models.HardDeadlineExpiredException(message, *args, **kwargs)

Bases: Exception

Should be raised regarding GroupComments if the deadline handling is hard, and the deadline has expired.

exception devilry.devilry_group.models.PeriodExpiredException(message, *args, **kwargs)

Bases: Exception

Should be raised regarding GroupComments if the period(semester) has expired.

class devilry.devilry_group.models.AbstractGroupCommentQuerySet(model=None, query=None, using=None, hints=None)

Bases: django.db.models.query.QuerySet

Base class for QuerySets for AbstractGroupComment.

exclude_private_comments_from_other_users(user)

Exclude all GroupComments with GroupComment.visibility set to GroupComment.VISIBILITY_PRIVATE and the GroupComment.user is not the user.

Parameters:user – The requestuser.
Returns:QuerySet of GroupComment not excluded.
Return type:QuerySet
exclude_is_part_of_grading_feedbackset_unpublished()

Exclude all GroupComment that has GroupComment.part_of_grading set to True if the GroupComment.feedback_set.grading_published_datetime is None.

Returns:QuerySet of GroupComment not excluded.
Return type:QuerySet
exclude_comment_is_not_draft_from_user(user)

Exclude GroupComment that are not drafts or the GroupComment.user is not the requestuser.

A GroupComment is a draft if GroupComment.visibility set to GroupComment.VISIBILITY_PRIVATE and GroupComment.part_of_grading is True.

Parameters:user – The requestuser
Returns:QuerySet of GroupComment not excluded.
Return type:QuerySet
class devilry.devilry_group.models.AbstractGroupComment(*args, **kwargs)

Bases: devilry.devilry_comment.models.Comment

The abstract superclass of all comments related to a delivery and feedback.

feedback_set

The related feedbackset. See FeedbackSet.

part_of_grading

If this is True, the comment is published when the feedbackset is published. This means that this comment is part of the feedback/grading from the examiner. The same visibility rules apply no matter if this is True or False, this only controls when the comment is published.

VISIBILITY_PRIVATE = 'private'

Choice for visibility.

VISIBILITY_VISIBLE_TO_EXAMINER_AND_ADMINS = 'visible-to-examiner-and-admins'

Comment should only be visible to examiners and admins that has access to the feedback_set. Choice for visibility.

VISIBILITY_VISIBLE_TO_EVERYONE = 'visible-to-everyone'

Comment should be visible to everyone that has access to the feedback_set. Choice for visibility.

VISIBILITY_CHOICES = [('private', 'Private'), ('visible-to-examiner-and-admins', 'Visible to examiners and admins'), ('visible-to-everyone', 'Visible to everyone')]

Choice list. Choices for visibility.

visibility

Sets the visibility choise of the comment. Defaults to VISIBILITY_VISIBLE_TO_EVERYONE.

clean()

Check for situations that should result in error.

Raises:ValidationError: Error occurs if user_role is 'student' and visibility is not set to VISIBILITY_VISIBLE_TO_EVERYONE | Error occurs if user_role is 'examiner' and part_of_grading is False and visibility is set to VISIBILITY_PRIVATE.
get_published_datetime()

Get the publishing datetime of the comment. Publishing datetime is the publishing time of the FeedbackSet if the comment has part_of_grading set to True, else it’s just the comments’ published_datetime.

Returns:Datetime.
publish_draft(time)

Sets the published datetime of the comment to time.

Parameters:time – publishing time to set for the comment.
copy_comment_into_feedbackset(feedbackset)

Creates a new GroupComment, copies all fields in self into the new comment and sets feedback_set foreign key to feedbackset :param feedbackset: FeedbackSet

Returns:GroupComment a new group comment
class devilry.devilry_group.models.FeedbackSetQuerySet(model=None, query=None, using=None, hints=None)

Bases: django.db.models.query.QuerySet

QuerySet for FeedbackSet.

get_order_by_deadline_datetime_argument()

Get a Coalesce expression that can be used with order_by() to order feedbacksets by deadline. This handles ordering the first feedbackset by the first deadline of the assignment.

Examples

Basics (same as using order_by_deadline_datetime()):

FeedbackSet.objects.all()                    .order_by(FeedbackSet.objects.get_order_by_deadline_datetime_argument())

Combine with other order by arguments:

FeedbackSet.objects.all()                    .order_by('group__parentnode__short_name',
              'group__id',
              FeedbackSet.objects.get_order_by_deadline_datetime_argument())
order_by_deadline_datetime()

Order by deadline_datetime.

Unlike just using order_by('deadline_datetime'), this method uses get_order_by_deadline_datetime_argument(), which ensures that the first feedbackset is ordered using the first deadline of the assignment.

has_public_comment_files_from_students(feedback_set)

Does the devilry.devilry_group.models.FeedbackSet have any public devilry.devilry_comment.models.CommentFile from students?

Parameters:feedback_set – The FeedbackSet to check.
Returns:True if any public student files, else False.
filter_public_comment_files_from_students()

Get all devilry.devilry_group.models.FeedbackSet with public comments from students.

Returns:A FeedbackSet queryset.
Return type:QuerySet
class devilry.devilry_group.models.FeedbackSet(*args, **kwargs)

Bases: django.db.models.base.Model

All comments that are given for a specific deadline (delivery and feedback) are linked to a feedback-set.

If the comment has instant_publish=True it will be published instantly, otherwise the comments will only be visible once the feedbackset is published. All student-comments will be instant_publish=True, and the same applies to comments made by examiners that are not a part of feedback.

group

The AssignmentGroup that owns this feedbackset.

FEEDBACKSET_TYPE_FIRST_ATTEMPT = 'first_attempt'

This means the feedbackset is basically the first feedbackset. Choice for feedbackset_type.

FEEDBACKSET_TYPE_NEW_ATTEMPT = 'new_attempt'

Is not the first feedbackset, but a new attempt. Choice for feedbackset_type

FEEDBACKSET_TYPE_RE_EDIT = 're_edit'

Something went wrong on grading, with this option, a new deadline should not be given to student. Student should just get notified that a new feedback was given. Choice for feedbackset_type.

FEEDBACKSET_TYPE_MERGE_FIRST_ATTEMPT = 'merge_first_attempt'

A merged first attempt feedbackset

FEEDBACKSET_TYPE_MERGE_NEW_ATTEMPT = 'merge_new_attempt'

A merged new attempt feedbackset

FEEDBACKSET_TYPE_MERGE_RE_EDIT = 'merge_re_edit'

A merged re edit feedbackset

FEEDBACKSET_TYPE_CHOICES = [('first_attempt', 'first attempt'), ('new_attempt', 'new attempt'), ('re_edit', 're edit'), ('merge_first_attempt', 'merge first attempt'), ('merge_new_attempt', 'merge new attempt'), ('merge_re_edit', 'merge re edit')]

Grading status choices for feedbackset_type.

feedbackset_type

Sets the type of the feedbackset. Defaults to FEEDBACKSET_TYPE_NEW_ATTEMPT.

ignored

Field can be set to True if a situation requires the FeedbackSet to not be counted as neither passed or failed but should be ignored, due to e.g sickness or something else. A reason for the FeedbackSet to be ignored must be provided in the ignored_reason.

ignored_reason

The reason for the FeedbackSet to be ignored.

ignored_datetime

The datetime for when the FeedbackSet was ignored.

created_by

The User that created the feedbackset. Only used as metadata for superusers (for debugging).

created_datetime

The datetime when this FeedbackSet was created.

last_updated_by

Last updated by. The user that was the last to make any changes on the FeedbackSet.

deadline_datetime

The datetime of the deadline. The first feedbackset in an AssignmentGroup (ordered by created_datetime) does not have a deadline. It inherits this from the first_deadline field of devilry.apps.core.models.assignment.Assignment.

grading_published_datetime

The datetime when the feedback was published. Set when an examiner publishes the feedback for this FeedbackSet.

When this is None, the feedbackset is not published. This means that no comments with AbstractGroupComment.part_of_grading set to True is visible, the grade (extracted from points) is not visible, and this feedbackset does not count when extracting the latest/active feedback/grade for the AssignmentGroup.

grading_published_by

Set when the feedbackset is published by an examiner. If this is None, the feedback is not published, and the points (grade) is not available to the student.

grading_points

Points given by examiner for this feedbackset. The points on the last published FeedbackSet is the current grade for the AssignmentGroup.

gradeform_data_json

A django.db.models.TextField for a gradeform filled or not filled for FeedbackSet.

clean()

Check for situations that should result in error.

Raises:ValidationError: Error occurs if ignored is True and ignored_reason is blank. | Error occurs if ignored_reason is filled and ignored is True. | Error occurs if grading_published_datetime has a datetime but grading_published_by is None. | Error occurs if grading_published_datetime has a datetime but grading_points is None.
can_add_comment(comment_user_role, assignment=None)

Check if comments and uploads should be disabled for this feedback set for the role of the comment.

This method raises a custom exception based on what why comments and uploads are not allowed:

Raises HardDeadlineExpiredException if the assignment for this feedback set has deadline handling set to hard, students can not upload or add comments.

Raises PeriodExpiredException if the period has expired, no one can upload or add comments.

A message will be provided with the exceptions.

Parameters:
  • comment_user_role – One of the choices for user_role. Comment.USER_ROLE_STUDENT, Comment.USER_ROLE_EXAMINER or Comment.USER_ROLE_ADMIN.
  • assignment – The assignment for this feedback set.
publish(published_by, grading_points, gradeform_data_json='')

Publishes this FeedbackSet and comments that belongs to this it and that are part of the grading.

Parameters:
  • published_by – Who published the feedbackset.
  • grading_points – Points to give to student(s).
  • gradeform_data_json – gradeform(coming soon).
Returns:

True or False and an error message.

copy_feedbackset_into_group(group, target=None)

Copy this feedbackset into target or create a new feedbackset, and set group foreign key to group

Parameters:
  • groupAssignmentGroup
  • targetFeedbackSet
Returns:

FeedbackSet a feedbackset with copied data from self

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class devilry.devilry_group.models.FeedbacksetPassedPreviousPeriod(*args, **kwargs)

Bases: django.db.models.base.Model

This model is used when a student have passed an assignment in previous period. Therefore we need to save some old data about the core.Assignment, devilry_group.FeedbackSet and core.Period from previous period.

feedbackset

Foreign key to classdevilry_group.FeedbackSet in current period.

passed_previous_period_type

The type of this entry. How it was generated.

assignment_short_name

Old core.Assignment.short_name.

assignment_long_name

Old core.Assignment.long_name.

created_datetime

When this entry was created.

created_by

Who this entry was created by.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class devilry.devilry_group.models.FeedbackSetGradingUpdateHistory(*args, **kwargs)

Bases: django.db.models.base.Model

Logs changes on the grading for a feedbackset.

If we have this history, there will be no problem changing the grades on an already corrected feedback set, as we can display the history, just as with FeedbackSetDeadlineHistory.

feedback_set

The FeedbackSet the update is for.

updated_by

The user that updated the feedback set.

updated_datetime

When the update was made.

old_grading_points

The score before update

old_grading_published_by

Who published the feedbackset before the update.

old_grading_published_datetime

Grading publishing datetime before update

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class devilry.devilry_group.models.FeedbackSetDeadlineHistory(*args, **kwargs)

Bases: django.db.models.base.Model

Logs change in deadline for a FeedbackSet.

feedback_set

The FeedbackSet the change is for.

changed_by

The User that made the deadline change.

changed_datetime

Time of change. Defaults to timezone.now.

deadline_old

The old deadline_datetime.

deadline_new

The new deadline_datetime.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class devilry.devilry_group.models.GroupCommentQuerySet(model=None, query=None, using=None, hints=None)

Bases: devilry.devilry_group.models.AbstractGroupCommentQuerySet

QuerySet for GroupComment.

class devilry.devilry_group.models.GroupComment(*args, **kwargs)

Bases: devilry.devilry_group.models.AbstractGroupComment

A comment made to an AssignmentGroup.

v2_id

v2 “<modelname>_<id>” This is only here to make it possible to debug and fix v2 migrations if anything goes wrong.

clean()

Check for situations that should result in error.

Raises:ValidationError: Error occurs if user_role is 'student' and visibility is not set to VISIBILITY_VISIBLE_TO_EVERYONE | Error occurs if user_role is 'examiner' and part_of_grading is False and visibility is set to VISIBILITY_PRIVATE.
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class devilry.devilry_group.models.GroupCommentEditHistoryQuerySet(model=None, query=None, using=None, hints=None)

Bases: django.db.models.query.QuerySet

exclude_private_comment_not_created_by_user(user)

Exclude all GroupCommentEditHistory entries that are private and where the comment is not created by the user.

Parameters:user – The user to check against.
class devilry.devilry_group.models.GroupCommentEditHistory(*args, **kwargs)

Bases: devilry.devilry_comment.models.CommentEditHistory

Model for logging changes in a GroupComment.

group_comment

The GroupComment the editing history is for.

visibility

Visibility state when log entry was created.

exception DoesNotExist

Bases: devilry.devilry_comment.models.DoesNotExist

exception MultipleObjectsReturned

Bases: devilry.devilry_comment.models.MultipleObjectsReturned

class devilry.devilry_group.models.ImageAnnotationCommentQuerySet(model=None, query=None, using=None, hints=None)

Bases: devilry.devilry_group.models.AbstractGroupCommentQuerySet

QuerySet for ImageAnnotationComment.

class devilry.devilry_group.models.ImageAnnotationComment(*args, **kwargs)

Bases: devilry.devilry_group.models.AbstractGroupComment

A comment made on a file, as an annotation

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Views API

class devilry.devilry_group.views.cradmin_feedbackfeed_base.GroupCommentForm(*args, **kwargs)

Bases: django.forms.models.ModelForm

Abstract class for creating a GroupComment.

Defines the attributes for the GroupComment form.

Examples

If you want to provide a check on the form data before save, just subclass this and add your custom clean logic:

class StandardGroupCommentForm(GroupCommentForm):

    def clean(self):
        super(GroupCommentForm, self).clean()
        if len(self.cleaned_data['text']) == 0 and self.cleaned_data['temporary_file_collection_id'] is None:
            raise ValidationError({
              'text': ugettext_lazy('A comment must have either text or a file attached, or both.'
                                    ' An empty comment is not allowed.')
            })
class devilry.devilry_group.views.cradmin_feedbackfeed_base.StandardGroupCommentForm(*args, **kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.GroupCommentForm

This should be used by all views that requires the comment to either contain a file/files OR text.

Failing to provide file/files or text will result in an error message. This is handled in clean.

clean()

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named ‘__all__’.

class devilry.devilry_group.views.cradmin_feedbackfeed_base.FeedbackFeedBaseView(**kwargs)

Bases: django_cradmin.viewhelpers.create.CreateView

Base feedbackfeed view.

The feedbackfeed view handles the options a certain devilryrole(student, examiner, ‘someadmin’) should have when the feedbackfeed view is rendered. Specialized views for each devilryrole must subclasses this class.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of devilry.devilry_group.models.GroupComment

post(request, *args, **kwargs)

Handles POST requests, instantiating a form instance with the passed POST variables and then checked for validity.

get(request, *args, **kwargs)

Handles GET requests and instantiates a blank version of the form.

get_devilryrole()

Get the devilryrole of a user. This function must be implemented by a subclass.

Raises:NotImplementedError – Raised if not implemented by subclass.
get_form_class()

Returns the form class to use in this view.

get_form_kwargs()

Returns the keyword arguments for instantiating the form.

get_hard_deadline_info_text()

Get hard deadline info text. Must be implemented in subclasses.

Uses function get_devilry_hard_deadline_info_text.

Returns:info text.
Return type:str
get_context_data(**kwargs)

Sets the context data needed to render elements in the template.

Parameters:**kwargs (dict) – Parameters to get_context_data.
Returns:The context data dictionary.
Return type:dict
get_available_commentfile_count_for_user()

Get the total amount of CommentFiles available for the student.

Returns:Count of CommentFiles available for the user.
Return type:(int)
get_button_layout()

Get the button layout. This is added to the crispy form layout.

Defaults to a crispy_forms.layout.Div with css class django_cradmin_submitrow containing all the buttons returned by get_buttons().

Returns:List of buttons.
Return type:list
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_field_layout()

Get a list/tuple of fields. These are added to a crispy_forms.layout.Layout. Defaults to a all fields on the model. If fields, we use those fields.

Simple example (same as specifying the fields in fields):

from crispy_forms import layout

class MyCreateView(CreateView):
    def get_field_layout(self):
        return [
            layout.Div(
                'title', 'name', 'size', 'tags',
                css_class='cradmin-globalfields')
        ]

A slightly more complex example:

from crispy_forms import layout

class MyCreateView(CreateView):
    def get_field_layout(self):
        return [
            layout.Div('title', css_class="cradmin-focusfield cradmin-focusfield-lg"),
            layout.Div('description', css_class="cradmin-focusfield"),
            layout.Fieldset('Metadata',
                'size',
                'tags'
            )

        ]
get_form(form_class=None)

If you set roleid_field, we will remove that field from the form.

Note

The roleid_field handling also works for GenericForeignKey fields (removes the content type and object pk field from the form).

set_automatic_attributes(obj)

Called by save_object() to set automatic attributes for the object before it is saved.

This is where we handle roleid_field, but you can override this to set your own automatic attributes. Just remember to call super if you want to keep the roleid_field magic.

Parameters:obj – The object you are about to save.
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

get_collectionqueryset()

Get a set of files from cradmins temporary fileuploadstore.

Returns:django_cradmin.TemporaryFileCollection objects.
Return type:QuerySet
get_success_message(object)

Override this to provide a success message.

The object is the saved object.

Used by add_success_messages().

Examiner view

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.AbstractFeedbackForm(*args, **kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.GroupCommentForm

Feedback-related forms regarding grading or creating a new FeedbackSet inherits from this.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.PassedFailedFeedbackForm(*args, **kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.AbstractFeedbackForm

Form for passed/failed grade plugin.

passed = None

Set delivery as passed or failed.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.PointsFeedbackForm(*args, **kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.AbstractFeedbackForm

Form for point-based grade plugin.

points = None

Set points that should be given to the delivery.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.EditGroupCommentForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None)

Bases: django.forms.models.ModelForm

Form for editing existing Feedback drafts.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.CreateFeedbackSetForm(*args, **kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.GroupCommentForm

Form for creating a new FeedbackSet (deadline).

deadline_datetime = None

Deadline to be added to the new FeedbackSet.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerBaseFeedbackFeedView(**kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.FeedbackFeedBaseView

Base view for examiner.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_hard_deadline_info_text()

Get hard deadline info text. Must be implemented in subclasses.

Uses function get_devilry_hard_deadline_info_text.

Returns:info text.
Return type:str
get_devilryrole()

Get the devilryrole for the view.

Returns:examiner as devilryrole.
Return type:str
set_automatic_attributes(obj)

Called by save_object() to set automatic attributes for the object before it is saved.

This is where we handle roleid_field, but you can override this to set your own automatic attributes. Just remember to call super if you want to keep the roleid_field magic.

Parameters:obj – The object you are about to save.
class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerFeedbackView(**kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerBaseFeedbackFeedView

The examiner feedbackview. This is the view where examiner corrects the delivery made by a student and is only able to create drafted comments, or publish grading.

If the last FeedbackSet is published, this view redirects to ExaminerFeedbackCreateFeedbackSetView. See dispatch().

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

dispatch(request, *args, **kwargs)

Checks if the last FeedbackSet in the group is published. If it’s published, a redirect response to ExaminerFeedbackCreateFeedbackSetView is returned.

Parameters:request – request object.
Returns:The HTTP response.
Return type:HttpResponse
get_form_class()

Get the correct form based on what grade plugin that is used.

Returns:A devilry.devilry_group.views.cradmin_feedbackfeed_base.GroupCommentForm
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

get_form_invalid_message(form)

You can override this to provide a custom error message.

Defaults to “Please fix the errors in the form below.”.

The form is the invalid form object.

Used by add_form_invalid_messages().

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerPublicDiscussView(**kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerBaseFeedbackFeedView

View for discussing with everyone on the group.

All comments posted here are visible to everyone that has access to the group.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

get_success_url()

Returns the supplied URL.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerWithAdminsDiscussView(**kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerBaseFeedbackFeedView

View for discussing with other examiners on the group and admins.

All comments posted here are only visible to examiners and admins with access to the group.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

get_success_url()

Returns the supplied URL.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerEditGradeView(**kwargs)

Bases: django_cradmin.viewhelpers.update.UpdateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

model

alias of devilry.devilry_group.models.FeedbackSet

get_pagetitle()

Get the page title (the title tag).

Defaults to Edit <verbose_name model>.

get_queryset_for_role(role)

Get a queryset with all objects of self.model that the current role can access.

get_form_class()

Returns the form class to use in this view.

set_automatic_attributes(obj)

Called by save_object() to set automatic attributes for the object before it is saved.

This is where we handle roleid_field, but you can override this to set your own automatic attributes. Just remember to call super if you want to keep the roleid_field magic.

Parameters:obj – The object you are about to save.
save_object(form, commit=True)

Save the object. You can override this to customize how the form is turned into a saved object.

Make sure you call super if you override this (see the docs for the commit parameter). If you do not, you will loose the automatic handling of obj:.roleid_field.

Parameters:commit (boolean) – If this is False, the object is returned unsaved. Very useful when you want to manipulate the object before saving it in a subclass.
Returns:The saved object.
get_field_layout()

Get a list/tuple of fields. These are added to a crispy_forms.layout.Layout. Defaults to a all fields on the model. If fields, we use those fields.

Simple example (same as specifying the fields in fields):

from crispy_forms import layout

class MyCreateView(CreateView):
    def get_field_layout(self):
        return [
            layout.Div(
                'title', 'name', 'size', 'tags',
                css_class='cradmin-globalfields')
        ]

A slightly more complex example:

from crispy_forms import layout

class MyCreateView(CreateView):
    def get_field_layout(self):
        return [
            layout.Div('title', css_class="cradmin-focusfield cradmin-focusfield-lg"),
            layout.Div('description', css_class="cradmin-focusfield"),
            layout.Fieldset('Metadata',
                'size',
                'tags'
            )

        ]
get_context_data(**kwargs)

Get the context data required to render the form view.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.GroupCommentEditDeleteMixin

Bases: object

Basic mixin/super-class for GroupCommentDeleteView and GroupCommentEditView.

model

alias of devilry.devilry_group.models.GroupComment

get_queryset_for_role(role)

Filter out devilry.devilry_group.models.GroupComment based on the role of role of the crinstance and the primarykey of the comment since in this case only a single comment should be fetched.

Parameters:role (GroupComment) – The roleclass for the crinstance.
Returns:QuerySet containing a single devilry.devilry_group.models.GroupComment.
Return type:QuerySet
class devilry.devilry_group.views.examiner.feedbackfeed_examiner.GroupCommentDeleteView(**kwargs)

Bases: devilry.devilry_group.views.examiner.feedbackfeed_examiner.GroupCommentEditDeleteMixin, django_cradmin.viewhelpers.delete.DeleteView

View for deleting an existing groupcomment with visibility set to private. When a groupcomment has visibility set to private, this means it’s a feedbackdraft.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

dispatch(request, *args, **kwargs)

Checks if the GroupComment id passed is for a drafted comment. If the comment is not a draft, PermissionDenied is raised.

Parameters:request (HttpRequest) – request object.
Returns:Reponse redirect object.
Return type:HttpResponseRedirect
Raises:PermissionDenied – If comment is not a draft, this exception is raised.
get_object_preview()

The preview of the object. Used when asking the user if he/she wants to delete the current object.

get_queryset_for_role(role)

Filter out devilry.devilry_group.models.GroupComment based on the role of role of the crinstance and the primarykey of the comment since in this case only a single comment should be fetched.

Parameters:role (GroupComment) – The roleclass for the crinstance.
Returns:QuerySet containing a single devilry.devilry_group.models.GroupComment.
Return type:QuerySet
get_success_url()

Get the URL to go to if object was deleted.

Defaults to the INDEX view of the current app.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.GroupCommentEditView(**kwargs)

Bases: devilry.devilry_group.views.group_comment_edit_base.EditGroupCommentBase

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.ExaminerFeedbackfeedRedirectView(**kwargs)

Bases: django.views.generic.base.View

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class devilry.devilry_group.views.examiner.feedbackfeed_examiner.App(appname, request, active_viewname)

Bases: django_cradmin.crapp.App

Admin view

class devilry.devilry_group.views.admin.feedbackfeed_admin.AdminBaseFeedbackFeedView(**kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.FeedbackFeedBaseView

Base view for admin.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_hard_deadline_info_text()

Get hard deadline info text. Must be implemented in subclasses.

Uses function get_devilry_hard_deadline_info_text.

Returns:info text.
Return type:str
get_devilryrole()

Get the devilryrole of a user. This function must be implemented by a subclass.

Raises:NotImplementedError – Raised if not implemented by subclass.
set_automatic_attributes(obj)

Called by save_object() to set automatic attributes for the object before it is saved.

This is where we handle roleid_field, but you can override this to set your own automatic attributes. Just remember to call super if you want to keep the roleid_field magic.

Parameters:obj – The object you are about to save.
get_context_data(**kwargs)

Sets the context data needed to render elements in the template.

Parameters:**kwargs (dict) – Parameters to get_context_data.
Returns:The context data dictionary.
Return type:dict
class devilry.devilry_group.views.admin.feedbackfeed_admin.AdminPublicDiscussView(**kwargs)

Bases: devilry.devilry_group.views.admin.feedbackfeed_admin.AdminBaseFeedbackFeedView

Admin view for public discussions.

Discussing with everyone on the AssignmentGroup.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

get_success_url()

Returns the supplied URL.

class devilry.devilry_group.views.admin.feedbackfeed_admin.AdminWithExaminersDiscussView(**kwargs)

Bases: devilry.devilry_group.views.admin.feedbackfeed_admin.AdminBaseFeedbackFeedView

Admin view for between admins and examiners.

Discussing with admins and examiners only on the AssignmentGroup.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

get_success_url()

Returns the supplied URL.

class devilry.devilry_group.views.admin.feedbackfeed_admin.AdminEditGroupCommentView(**kwargs)

Bases: devilry.devilry_group.views.group_comment_edit_base.EditGroupCommentBase

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class devilry.devilry_group.views.admin.feedbackfeed_admin.App(appname, request, active_viewname)

Bases: django_cradmin.crapp.App

Student view

class devilry.devilry_group.views.student.feedbackfeed_student.StudentFeedbackFeedView(**kwargs)

Bases: devilry.devilry_group.views.cradmin_feedbackfeed_base.FeedbackFeedBaseView

Student view. Handles what should be rendered for a student on the FeedbackFeed.

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_heading_text_template_name()

Get template for rendering a heading text in the form.

Override this to provide an explanatory text added to the heading of the form for posting a comment. This should include some information about what happens when a comment is posted.

Returns:a string or path to html template or None.
Return type:(str)
get_hard_deadline_info_text()

Get hard deadline info text. Must be implemented in subclasses.

Uses function get_devilry_hard_deadline_info_text.

Returns:info text.
Return type:str
get_devilryrole()

Get the devilryrole for the view.

Returns:student as devilryrole.
Return type:str
get_buttons()

Get buttons for the form, normally one or more submit button.

Each button must be a crispy form layout object, typically some subclass of crispy_forms.layout.Submit.

See:
This method is used by get_button_layout().
set_automatic_attributes(obj)

Called by save_object() to set automatic attributes for the object before it is saved.

This is where we handle roleid_field, but you can override this to set your own automatic attributes. Just remember to call super if you want to keep the roleid_field magic.

Parameters:obj – The object you are about to save.
save_object(form, commit=False)

How post of the comment should be handled. This can be handled more specifically in subclasses.

Add call to super in the subclass implementation on override.

Parameters:
Returns:

The form-object GroupComment.

Return type:

GroupComment

perform_after_save(comment)

This method is called if the comment posted is saved and commit is True. This means that both the comment and files uploaded with it is saved in the database.

Override this function for operations that require that the comment is saved, such as email sending etc.

class devilry.devilry_group.views.student.feedbackfeed_student.StudentEditGroupComment(**kwargs)

Bases: devilry.devilry_group.views.group_comment_edit_base.EditGroupCommentBase

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

class devilry.devilry_group.views.student.feedbackfeed_student.App(appname, request, active_viewname)

Bases: django_cradmin.crapp.App

Using ListBuilder to render the feedbackfeed.

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.TimeLineListBuilderList

Bases: django_cradmin.viewhelpers.listbuilder.base.List

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.FeedbackSetTimelineListBuilderList(feedbackset, group, assignment, requestuser, devilryrole)

Bases: django_cradmin.viewhelpers.listbuilder.base.List

A list of all events for a specific FeedbackSet.

classmethod from_built_timeline(built_timeline, feedbackset, attempt_num, **kwargs)

Creates a instance of TimelineListBuilderList.

Appends events from built_timeline.

Parameters:
  • built_timeline – The built and sorted feedbackfeed timeline
  • feedbackset – The FeedbackSet the events belong to.
  • attempt_num – The chronological number of the feedbackset.
Returns:

listbuilder instance.

Return type:

TimelineListBuilderList

get_item_value(event_dict)

Creates a ItemValueRenderer based on the event type.

If the event type is comment:
  • create and return a StudentGroupCommentItemValue, ExaminerGroupCommentItemValue or AdminGroupCommentItemValue.
If the event type is deadline_created:
  • create and return a DeadlineCreatedItemValue.
If the event type is deadline_expired:
  • create and return a DeadlineExpiredItemValue.
If the event type is grade:
  • create and return a DeadlineExpiredItemValue.
Parameters:event_dict – Event metadata dictionary.
Returns:Subclass of BaseItemValue.
Return type:BaseItemValue
get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.FeedbackSetContentList(feedbackset, renderables_list)

Bases: django_cradmin.viewhelpers.listbuilder.base.List

Simply adds a css wrapper-class for all events that belong to a feedbackset.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseItemValue(*args, **kwargs)

Bases: django_cradmin.viewhelpers.listbuilder.base.ItemValueRenderer

Base class for all items in the list.

devilry_viewrole

Get the devilry role for the view.

Returns:‘student’, ‘examiner’ or a admin role.
Return type:str
get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseEventItemValue(*args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseItemValue

Base class for all events.

Superclass for all events that occur in the timeline such as deadline created, deadline expired, grading passed and grading failed.

get_timeline_datetime()

Get the timeline datetime for the event.

Returns:The event datetime
Return type:DateTime
Raises:NotImplementedError – if not implemented.
get_base_css_classes_list()

Override this to set your own css classes.

changed_by_user_id

ID of the user that made the change.

This must be implemented in each subclass as this dependent on the model-obj set as self.value.

Returns:A user ID.
Return type:int
show_changed_by_user

If the user should be rendered, based on the the role of the requestuser and if the assignment is anonymized.

Returns:True
Return type:bool
class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.FeedbackSetCreatedItemValue(attempt_num, assignment, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseItemValue

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseItemValue

Base class for a GroupComment item.

Superclass for the different types of comments(student-comment, examiner-comment and admin-comment).

Render links for editing GroupComment.

include_badge()

Include right-hand-badge with comment-info in GroupComment.

include_published_last_edited_datetime()

Include the last published datetime, or edited datetime if edited, in GroupComment.

include_files()

Render uploaded files for a GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.StudentGroupCommentItemValue(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Student GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.StudentGroupCommentItemValueMinimal(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Student GroupComment minimal renderable.

Only shows the publish datetime, user, and text. Files and badges are excluded

Render links for editing GroupComment.

include_badge()

Include right-hand-badge with comment-info in GroupComment.

include_published_last_edited_datetime()

Include the last published datetime, or edited datetime if edited, in GroupComment.

include_files()

Render uploaded files for a GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.ExaminerGroupCommentItemValue(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Examiner GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.ExaminerGroupCommentItemValueMinimal(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Render links for editing GroupComment.

include_badge()

Include right-hand-badge with comment-info in GroupComment.

include_published_last_edited_datetime()

Include the last published datetime, or edited datetime if edited, in GroupComment.

include_files()

Render uploaded files for a GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.AdminGroupCommentItemValue(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Admin GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.AdminGroupCommentItemValueMinimal(requestuser, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseGroupCommentItemValue

Render links for editing GroupComment.

include_badge()

Include right-hand-badge with comment-info in GroupComment.

include_published_last_edited_datetime()

Include the last published datetime, or edited datetime if edited, in GroupComment.

include_files()

Render uploaded files for a GroupComment.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.AbstractDeadlineEventItemValue(*args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseEventItemValue

Abstract class for deadline events.

get_timeline_datetime()

Get the timeline datetime for the event.

Returns:The event datetime
Return type:DateTime
Raises:NotImplementedError – if not implemented.
class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.DeadlineMovedItemValue(is_last=False, *args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.AbstractDeadlineEventItemValue

Deadline moved event.

get_timeline_datetime()

Get the timeline datetime for the event.

Returns:The event datetime
Return type:DateTime
Raises:NotImplementedError – if not implemented.
changed_by_user_id

ID of the user that made the change.

This must be implemented in each subclass as this dependent on the model-obj set as self.value.

Returns:A user ID.
Return type:int
get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.DeadlineExpiredItemValue(*args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.AbstractDeadlineEventItemValue

Deadline expired event.

get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.GradeItemValue(*args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseEventItemValue

Grading event.

changed_by_user_id

ID of the user that made the change.

This must be implemented in each subclass as this dependent on the model-obj set as self.value.

Returns:A user ID.
Return type:int
get_timeline_datetime()

Get the timeline datetime for the event.

Returns:The event datetime
Return type:DateTime
Raises:NotImplementedError – if not implemented.
get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

class devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.GradingUpdatedItemValue(*args, **kwargs)

Bases: devilry.devilry_cradmin.devilry_listbuilder.feedbackfeed_timeline.BaseEventItemValue

changed_by_user_id

ID of the user that made the change.

This must be implemented in each subclass as this dependent on the model-obj set as self.value.

Returns:A user ID.
Return type:int
get_timeline_datetime()

Get the timeline datetime for the event.

Returns:The event datetime
Return type:DateTime
Raises:NotImplementedError – if not implemented.
get_extra_css_classes_list()

Override this to set your own css classes. Must return a list of css classes.

This is reserved for setting css classes when extending a reusable component.

See get_css_classes_string().

Writing tests

In most cases, just using model_mommy (mommy.make) should be enough, but we provide some factory-methods that makes this a bit easier.

Example - create a group with two “attempts”

testgroup = mommy.make('core.AssignmentGroup',
                           parentnode__first_deadline=timezone.now() - timedelta(days=10)
    devilry_group_mommy_factories.feedbackset_first_attempt_published(
        group=testgroup,
        grading_points=10,
        deadline_datetime=timezone.now() - timedelta(days=10),
        is_last_in_group=False)
    devilry_group_mommy_factories.feedbackset_new_attempt_published(
        group=testgroup,
        grading_points=20,
        is_last_in_group=True)
devilry.devilry_group.devilry_group_mommy_factories.feedbackset_save(feedbackset, **kwargs)

Set attributes for a FeedbackSet-instance and save it.

Parameters:feedbackset – FeedbackSet to save.
devilry.devilry_group.devilry_group_mommy_factories.make_first_feedbackset_in_group(group=None, **feedbackset_attributes)

Get the first feedbackset in a group, and optionally update some attributes.

This is designed to be used instead of mommy.make('devilry_group.FeedbackSet') when you just want a FeedbackSet since that does not work because the postgres triggers automatically create the first feedbackset in each created AssignmentGroup.

Examples

Create a FeedbackSet:

feedbackset = devilry_group_mommy_factories.make_first_feedbackset_in_group()

With attributes:

feedbackset = devilry_group_mommy_factories.make_first_feedbackset_in_group(
    ignored_reason='Test')

With pre-existing AssignmentGroup:

group = mommy.make('core.AssignmentGroup')
feedbackset = devilry_group_mommy_factories.make_first_feedbackset_in_group(
    group=group)

Create AssignmentGroup with attributes:

group = mommy.make('core.AssignmentGroup')
feedbackset = devilry_group_mommy_factories.make_first_feedbackset_in_group(
    group__parentnode__short_name='assignment1',
    group__parentnode__parentnode__short_name='period1')
Parameters:
  • group (devilry.apps.core.models.assignment_group.AssignmentGroup) – An AssignmentGroup. If this is None, the group is created using mommy.make(), and all the attributes in feedbackset_attributes starting with group__.
  • **feedbackset_attributes – Optional attributes for the feedbackset. If provided, the feedbackset is updated with these attributes (and saved to the database). Does not clean before saving.
Returns:

The retrieved

(and updated if feedbackset_attributes is provided) FeedbackSet.

Return type:

devilry.devilry_group.models.FeedbackSet

devilry.devilry_group.devilry_group_mommy_factories.feedbackset_first_attempt_published(group=None, grading_published_datetime=None, grading_points=1, **kwargs)

Updates the autogenerated FeedbackSet.

Creates a published FeedbackSet with feedbackset_type=FeedbackSet.FEEDBACKSET_TYPE_NEW_ATTEMPT using mommy.make('devilry_group.FeedbackSet).

Note::
If no group is passed as parameter(param group is None), an AssignmentGroup will be created which triggers an automatic creation of a FeedbackSet. This is the FeedbackSet that is returned. An examiner is also autogenerated for FeedbackSet.grading_published_by.
Parameters:
  • group – AssignmentGroup for the first FeedbackSet.
  • grading_published_datetime – The grading_published_datetime of the feedbackset. Defaults to timezone.now() if not specified.
  • grading_points – The grading_points of the feedbackset. Defaults to 1.
  • kwargs – Other attributes for FeedbackSet.
Returns:

Instance of the first FeedbackSet.

Return type:

FeedbackSet

devilry.devilry_group.devilry_group_mommy_factories.feedbackset_first_attempt_unpublished(group=None, **kwargs)

Creates a unpublished FeedbackSet with feedbackset_type=FeedbackSet.FEEDBACKSET_TYPE_NEW_ATTEMPT using mommy.make('devilry_group.FeedbackSet).

Note::
If no group is passed as parameter(param group is None), an AssignmentGroup will be created which triggers an automatic creation of a FeedbackSet. This is the FeedbackSet that is returned.
Parameters:
  • group – AssignmentGroup for the first FeedbackSet.
  • kwargs – Other attributes for FeedbackSet.
Returns:

Instance of the first FeedbackSet.

Return type:

FeedbackSet

devilry.devilry_group.devilry_group_mommy_factories.feedbackset_new_attempt_published(group, grading_published_datetime=None, grading_points=1, **kwargs)

Creates a published FeedbackSet with feedbackset_type=FeedbackSet.FEEDBACKSET_TYPE_NEW_ATTEMPT using mommy.make('devilry_group.FeedbackSet).

Parameters:
  • group – The AssignmentGroup the FeedbackSet should belong to.
  • grading_published_datetime – The grading_published_datetime of the feedbackset. Defaults to timezone.now() if not specified.
  • grading_points – The grading_points of the feedbackset. Defaults to 1.
  • kwargs – Other attributes for FeedbackSet.
Returns:

The created FeedbackSet.

Return type:

FeedbackSet

devilry.devilry_group.devilry_group_mommy_factories.feedbackset_new_attempt_unpublished(group, **kwargs)

Creates a unpublished FeedbackSet with feedbackset_type=FeedbackSet.FEEDBACKSET_TYPE_NEW_ATTEMPT using mommy.make('devilry_group.FeedbackSet).

Parameters:
  • group – The AssignmentGroup the FeedbackSet should belong to.
  • kwargs – Other attributes for FeedbackSet.
Returns:

The created FeedbackSet.

Return type:

FeedbackSet

devilry.devilry_group.devilry_group_mommy_factories.temporary_file_collection_with_tempfile(**collection_attributes)

Create a django_cradmin.apps.cradmin_temporaryfileuploadstore.models.TemporaryFileCollection using mommy.make('cradmin_temporaryfileuploadstore.TemporaryFileCollection') with a attached default django_cradmin.apps.cradmin_temporaryfileuploadstore.models.TemporaryFile.

Note::
Use this if you don’t care for the actual file, only that a file is added.
Parameters:**temporary_filecollection_attributes – Attributes for TemporaryFileCollection.
Returns:TemporaryFileCollection instance.
Return type:cradmin_temporaryfileuploadstore.TemporaryFileCollection
devilry.devilry_group.devilry_group_mommy_factories.temporary_file_collection_with_tempfiles(file_list=None, **collection_attributes)

Create a django_cradmin.apps.cradmin_temporaryfileuploadstore.models.TemporaryFileCollection using mommy.make('cradmin_temporaryfileuploadstore.TemporaryFileCollection').

Add files to the file_list, preferably Django`s SimpleUploadedFile.

Examples

Create a TemporaryFileCollection with TemporaryFiles (adds 3 files):

devilry_group_mommy_factories.temporary_file_collection_with_tempfiles(
    file_list=[
        SimpleUploadedFile(name='testfile1.txt', content=b'Test content 1', content_type='text/txt'),
        SimpleUploadedFile(name='testfile1.txt', content=b'Test content 1', content_type='text/txt'),
        SimpleUploadedFile(name='testfile1.txt', content=b'Test content 1', content_type='text/txt')
    ],
    # attributes for the TemporaryFileCollection
    ...
)
Parameters:
  • file_list – A list of files implementing the general attributes of a file.
  • **collection_attributes – Attributes for TemporaryFileCollection.
Returns:

TemporaryFileCollection.

Return type:

cradmin_temporaryfileuploadstore.TemporaryFileCollection