Welcome to marsha’s documentation!¶
About¶
🐠 A FUN video provider for Open edX
ADR - Architecture Decision Records¶
Purpose¶
These are the architectural decisions that are taken while developing Marsha.
The format is based on Michael Nygard’s article on the subject.
Proposed¶
Accepted¶
ADR 0001 - Actors¶
Status¶
Accepted
Context¶
There are different kinds of actors that need to interact with Marsha.
First we have the people managing a Marsha instance.
Then we have people linking their own website (this website is a “consumer site”) to a Marsha instance, to host videos.
These consumer sites can host many publishers. We call these “organizations”. And these organizations have managers that can administrate some things about authors, video sharing between authors…
Next we have the video authors, belonging to the organizations.
And finally we have the users coming to watch videos.
Decision¶
Let’s separate those 5 actors / roles:
“staff”¶
To manage a Marsha instance
These are simply instances of the Django User
model, with the flag is_staff
set to True
.
“admins”¶
To manage the link between a consumer site and a Marsha instance, and the organizations allowed to access this consumer site on the instance.
To represent a consumer site on a Marsha instance, we have a ConsumerSite
Django model. With a ManyToMany
link to the User
model, named admins
(not a single admin, to avoid having no admin if the only one existing is not available anymore)).
“managers”¶
To manage the authors in the organization (an organization could be present on many consumer sites). To allow videos to be private to authors or public for all authors. And create courses.
To represent an organization on a Marsha instance, we have an Organization
Django model. With a ManyToMany
link to the User
model, named managers
.
“authors”¶
To post videos on a Marsha instance to be used on a consumer site.
An author is simply an instance of the User
model, but has a link to an Organization
via a ManyToMany
link, named organizations
(we can imagine an author working for many organizations).
“viewers”¶
To watch videos hosted on a Marsha instance.
For the viewers we don’t need to save anything in the database, so there is no instances of the User
Django model for them.
Each time a user does an action to view a video, they access it via a url containing a unique token, with a limited life span. It’s this token that grant them access to the video.
This is not the scope of this document to address token generations.
To store the user preferences regarding languages, video resolution, etc, it can simply be done via a cookie.
ADR 0002 - Videos languages¶
Status¶
Accepted
Context¶
We want to think Marsha as accessible from the beginning. At least from the point of view of the videos, which are the main content available.
We can think about a video as a main content, with many auxiliary contents.
Auxiliary contents¶
We have a main video, with an audio track included. The author could propose many other audio tracks, as audio files, and in the player the viewer can change the one to use.
In addition to audio tracks, many subtitles tracks can be available.
Some people with disabilities could want a video with the sign language transcript. For this it can be a video incorporated in the original one, or an other video displayed on the site.
As sign languages are not the same for every spoken language, there can be several sign languages videos for a single video.
Decision¶
We decided to take all these elements into account right from the beginning.
So we have a main Django model named Video
, from an author, with the link to to main video file, including the default audio track.
For the other audio tracks, we have AudioTrack
Django model, with a ForeignKey
to the Video
instance, named video
, and a language
field (with only one audio track for each video+language)
It’s the same for the subtitles, we have a SubtitleTrack
Django model, with the same video
and language
fields, but with an additional cc
field to indicate that this subtitle track is “closed captioning”, ie a subtitles track for deaf or hard of hearing viewers. So there can be two subtitle tracks for each video+language: one with cc
on, one with cc
off.
And finally, for sign-languages videos, it’s the same as for audio tracks: a Django model named SignTrack
with the same video
and language
field.
Consequences¶
Accessibility is implemented from the start. Even if we decide to hide some things, the main concepts are here.
ADR 0003 - Content organization and accesses¶
Status¶
Accepted
Context¶
We have actors. And videos, with their auxiliary files, that we’ll call for now “content”. We want this content to be organized for actors to manage/view them.
Decision¶
Videos are grouped in playlists, which is a Django model named Playlist
. A playlist belongs to an organization (Organization
model defined in actors) and is created by someone who can be a manager of this organization, or an author who belongs to this organization. This link is materialized by an author
field on the Playlist
model, a ForeignKey
to the User
model.
The manager can allow many actors to manage a playlist, so there is a ManyToMany
field on the Playlist
model, named editors
, pointing to the User
model. And instead of relying on the hidden model created by Django when creating a ManyToMany
, we’ll define this model and use it via the through
argument, to be able to add more rights constraints later if needed.
The author of the playlist is automatically added to this list of editors. And can be removed from it by a manager, still staying marked as the author, but being the author itself doesn’t involve any rights.
A playlist can be duplicated by a manager, and if it stays in the same organization, the manager can clear or keep the list of editors. If it is to be duplicated in another organization, the list of editors will be cleared of actors not belonging to the new organization, and the manager will still be able to clear it all or keep the remaining editors.
When duplicated, a new instance of Playlist
is created, with a link to the original playlist, keeping the author. We do the same for each instances of the Video
linked to this playlist, but we will still point to the same files (videos/audios/subtitles…) on the hosting provider, to keep cost manageable.
And finally, there is a flag named is_public
on the playlist, that can be toggled by a manager, to tell if the playlist can be viewed by anyone or only by people who were granted access to it. This kind of access is not in the scope of this document.
Consequences¶
Videos are grouped, which ease search and maintenance.
It is easy to change and check the rights for people to manage such a playlist.
ADR 0004 - Soft deletion¶
Status¶
Accepted
Context¶
We have users and objects, and everything is tied together. Deleting something may cause some problems, like deleting other things in cascade, or losing some relatioship, like not knowing who is the author of a video.
Decision¶
We don’t want things to be deleted, instead we’ll keep them in the database in a “deleted” state, so that they won’t show up anywhere.
Looking at the ` Safe/Soft/Logical deletion/trashing and restoration/undeletion <https://djangopackages.org/grids/g/deletion/>`_ page on djangopackages, we can make a choice with these constraints:
- support for python 3 and django 2
- simple, not over-featured
- can manage relationships
- supports the django admin
- is maintained
Regarding this, we choose django-safedelete which proposes many options to handle deletion, and so will fit our needs.
Consequences¶
If the correct deletion options are used, depending on the relationships, we won’t lose data.
No new code to write to handle soft-deletion.
As a cons: one more dependency, but it seems maintained so it should be ok.
Deprecated¶
Superseded¶
Development¶
At the time of writing, Marsha is developed with Python 3.6 for Django 2.0.
Code quality¶
We enforce good code by using some linters and auto code formatting tools.
To run all linters at once, run the command:
make lint
You can also run each linter one by one. We have ones for the following tools:
black¶
We use black to automatically format python files to produce pep 8 compliant code.
The best is to configure your editor to automatically update the files when saved.
If you want to do this manually, run the command:
make black
And to check if all is correct without actually modifying the files:
make check-black
flake8¶
In addition to black auto-formatting, we pass the code through
flake8 to check for a lot of rules. In addition to the default flake8
rules, we use these plugins:
- flake8-bugbear to find likely bugs and design problems.
- flake8-comprehensions to helps write better list/set/dict comprehensions.
- flake8-imports to check imports order via
isort
. - flake8-mypy to check typing inconsistencies via
mypy
(see mypy). - flake8-docstrings to check docstrings (see Docstrings)
To check your code, run the command:
make flake8
pylint¶
To enforce even more rules than the ones provided by flake8, we use pylint (with the help of pylint-django).
pylint
may report some violations not found by flake8
, and vice-versa. More often, both will report the same ones.
To check your code, run the command:
make pylint
mypy¶
We use python typing as much as possible, and mypy (with the help of mypy-django) to check it.
We also enforce it when defining Django fields, via the use of a “Django check”. And the type of reverse related fields must always be defined.
To check if your code is valid for mypy, run the following command:
make mypy
Following is how the types of fields must be defined. To check if some fields typing is invalid, among other problems, run the following command:
make check-django
It will tell you all found errors in typing, with indication on how to correct them.
Scalar fields¶
For scalar fields (CharField
, IntegerField
, BooleanField
, DateField
…), we just add the type.
For each type of Django field, there is an expected type. Theses types are defined in the fields_type_mapping
dict defined in marsha.core.base_models
. Add the missing ones if needed.
class Foo(models.Model):
# we tell mypy that the attribute ``bar`` is of type ``str``
name: str = models.CharField(...)
One-to-one fields¶
The type expected for a OneToOneField
is the pointed model.
And on the pointed model we set the type of the related name to the source model.
class Foo(models.Model):
# we tell mypy that the attribute ``bar`` is of type ``Bar``
bar: "Bar" = models.OneToOneField(to=Bar, related_name="the_foo")
class Bar(models.Model):
# we tell mypy that the class ``Bar`` has an attribute ``the_foo`` of type ``Foo``
the_foo: Foo
Foreign keys¶
The type expected for a ForeignKey
is the pointed model.
On the pointed model we have a many-to-one relationship.
We use a type specifically defined for that, ReverseFKType
, defined in marsha.stubs
.
from marsha.stubs import ReverseFKType
class Foo(models.Model):
# we tell mypy that the attribute ``bar`` is of type ``Bar``
bar: "Bar" = models.ForeignKey(to=Bar, related_name="foos")
class Bar(models.Model):
# we tell mypy that the class ``Bar`` has an attribute ``foos``
# which is a reverse foreign key for the class ``Foo``
foos: ReverseFKType[Foo]
Many-to-many fields¶
To define the type of a ManyToManyField
, we use a type specifically defined for that, M2MType
, defined in
marsha.stubs
.
On the pointed model, we use the same type, as it’s also a many-to-many fields (ie it could have been defined in one model or the other).
from marsha.stubs import M2MType
class Foo(models.Model):
# we tell mypy that the attribute ``bar`` is a many-to-many for the class ``Bar``
bars: M2MType["Bar"] = models.ManyToManyField(to=Bar, related_name="foos")
class Bar(models.Model):
# we tell mypy that the class ``Bar`` has an attribute ``foos``
# which is a many-to-many for the class ``Foo``
foos: M2MType[Foo]
Docstrings¶
flake8 is configured to enforce docstrings rule defined in the pep 257
In addition, we document function arguments, return types, etc… using the “NumPy” style documentation, which will be validated by flake8.
Django¶
Opinionated choices¶
We made the opinionated choice of following this document, “Tips for Building High-Quality Django Apps at Scale”.
In particular:
- Do not split code in many Django applications if code is tightly coupled.
- Applications are inside the
marsha
package, not at root, so import are done like this:
from marsha.someapp.foo import bar
- Database tables are specifically named: we do not rely on the Django auto-generation. And then we don’t prefix theses
tables with the name of the project or the app. For example, a model named
Video
, will have thedb_table
attribute of itsMeta
class set tovideo
. Enforced by a “Django check”. - Through tables for
ManyToManyField
relations must be defined. Enforced by a “Django check”.
In addition:
- We enforce typing of fields and reverse related fields (see mypy). Enforced by a “Django check”.
- We enforce defining a related name for all related field (
ManyToManyField
,ForeignKey
,OneToOneField
). Enforced by a “Django check”.
To check if theses rules are correctly applied, among other rules defined by Django itself, run:
make check-django
Note
for these checks to work, all models must inherit from BaseModel
defined in marsha.core.base_models
.
Specific libraries¶
Here are a list of specific Django libraries we chose to use and why.
django-configurations¶
The aim is to be more specific about inheritance in settings from doc to staging to production, instead of relying on
multiple files (and changing the DJANGO_SETTINGS_MODULE
environment variable accordingly), using the
from .base import *
pattern.
It also provides tools to get some variables from the environment and validating them.
As a consequence of this tool, some default behavior of Django don’t work anymore. It’s why the django-admin
bash command is redefined in setup.cfg
.
django-safedelete¶
We don’t want to lose data, so everything is kept in database, but hidden from users.
See ADR 0004 - Soft deletion for details about the reasoning behind this choice.
django-postgres-extra¶
With django-safedelete
, model instances are not deleted but saved with a field deleted
changing from None
to
the deletion date-time.
So we cannot anymore use unique_together
.
django-postgres-extra
provides a ConditionalUniqueIndex
index, that acts like unique_together
, but with a
condition. We use the condition WHERE "deleted" IS NULL
, to enforce the fact that only one non-deleted instance
matching the fields combination can exist.
Tests¶
The whole Marsha project is tested.
Run this command to run all the tests:
make test
If you want to be more specific about the tests to run, use the Django command:
django-admin test marcha.path.to.module
django-admin test marcha.path.to.module.Class
django-admin test marcha.path.to.module.Class.method
Makefile¶
We provide a Makefile
that allow to easily perform some actions.
- make install
- Will install the project in the current environment, with its dependencies.
- make dev
- Will install the project in the current environment, with its dependencies, including the ones needed in a development environment.
- make dev-upgrade
- Will upgrade all default+dev dependencies defined in setup.cfg.
- make check
- Will run all linters and checking tools.
- make lint
- Will run all linters (mypy, black, flake8, pylint)
- make mypy
- Will run the mypy tool.
- make check-black
- Will run the black tool in check mode only (won’t modify files)
- make black
- Will run the black tool and update files that need to.
- make flake8
- Will run the flake8 tool.
- make pylint
- Will run the pylint tool.
- make check-django
- Will run the Django
check
command. - make check-migrations
- Will check that all needed migrations exist.
- make tests
- Will run django tests for the marsha project.
- make doc
- Will build the documentation.
- make dist
- Will build the package.
- make clean
- Will clean python build related directories and files.
- make full-clean
- Like
make clean
but will clean some other generated directories or files.
Environment variables¶
We try to follow 12 factors app and so use environment variables for configuration.
Here is a list of the ones that are needed or optional:
DJANGO_SETTINGS_MODULE¶
- Description
- Define the settings file to use
- Type
- String
- Mandatory
- Yes
- Default
- None
- Choices
- Must be set to
marsha.settings
DJANGO_CONFIGURATION¶
- Description
- Define the configuration to use in settings
- Type
- String
- Mandatory
- Yes
- Default
- None
- Choices
- Actually only
Dev
is available
DJANGO_SECRET_KEY¶
- Description
- Used to provide cryptographic signing, and should be set to a unique, unpredictable value
- Type
- String
- Mandatory
- Yes
- Default
- None
DJANGO_DEBUG¶
- Description
- Turns on/off debug mode
- Type
- Boolean
- Mandatory
- No
- Default
True
ifDJANGO_CONFIGURATION
is set toDev
,False
otherwise- Choices
True
orFalse
DATABASE_URL¶
- Description
- URL to represent the connection string to a database
- Type
- String
- Mandatory
- No if
DJANGO_CONFIGURATION
is set toDev
, yes otherwise - Default
sqlite:///path/to/project/db.sqlite3
ifDJANGO_CONFIGURATION
is set toDev
, None otherwise- Choices
- See schemas as presented by dj-database-url
marsha¶
marsha package¶
Subpackages¶
marsha.core package¶
Subpackages¶
-
class
marsha.core.migrations.0001_initial_models.
Migration
(name, app_label)[source]¶ Bases:
django.db.migrations.migration.Migration
-
dependencies
= [('auth', '0009_alter_user_last_name_max_length')]¶
-
initial
= True¶
-
operations
= [<CreateModel name='User', fields=[('id', <django.db.models.fields.AutoField>), ('password', <django.db.models.fields.CharField>), ('last_login', <django.db.models.fields.DateTimeField>), ('is_superuser', <django.db.models.fields.BooleanField>), ('username', <django.db.models.fields.CharField>), ('first_name', <django.db.models.fields.CharField>), ('last_name', <django.db.models.fields.CharField>), ('email', <django.db.models.fields.EmailField>), ('is_staff', <django.db.models.fields.BooleanField>), ('is_active', <django.db.models.fields.BooleanField>), ('date_joined', <django.db.models.fields.DateTimeField>), ('groups', <django.db.models.fields.related.ManyToManyField>), ('user_permissions', <django.db.models.fields.related.ManyToManyField>)], options={'verbose_name': 'user', 'verbose_name_plural': 'users', 'db_table': 'user'}, managers=[('objects', <django.contrib.auth.models.UserManager object>)]>, <CreateModel name='AudioTrack', fields=[('id', <django.db.models.fields.AutoField>), ('language', <django.db.models.fields.CharField>)], options={'verbose_name': 'audio track', 'verbose_name_plural': 'audio tracks', 'db_table': 'audio_track'}>, <CreateModel name='Authoring', fields=[('id', <django.db.models.fields.AutoField>)], options={'verbose_name': 'author in organization', 'verbose_name_plural': 'authors in organizations', 'db_table': 'authoring'}>, <CreateModel name='ConsumerSite', fields=[('id', <django.db.models.fields.AutoField>), ('name', <django.db.models.fields.CharField>)], options={'verbose_name': 'site', 'verbose_name_plural': 'sites', 'db_table': 'consumer_site'}>, <CreateModel name='Organization', fields=[('id', <django.db.models.fields.AutoField>), ('name', <django.db.models.fields.CharField>), ('authors', <django.db.models.fields.related.ManyToManyField>)], options={'verbose_name': 'organization', 'verbose_name_plural': 'organizations', 'db_table': 'organization'}>, <CreateModel name='OrganizationManager', fields=[('id', <django.db.models.fields.AutoField>), ('organization', <django.db.models.fields.related.ForeignKey>), ('user', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'organization manager', 'verbose_name_plural': 'organizations managers', 'db_table': 'organization_manager'}>, <CreateModel name='Playlist', fields=[('id', <django.db.models.fields.AutoField>), ('is_public', <django.db.models.fields.BooleanField>), ('author', <django.db.models.fields.related.ForeignKey>), ('duplicated_from', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'playlist', 'verbose_name_plural': 'playlists', 'db_table': 'playlist'}>, <CreateModel name='PlaylistAccess', fields=[('id', <django.db.models.fields.AutoField>), ('playlist', <django.db.models.fields.related.ForeignKey>), ('user', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'playlist access', 'verbose_name_plural': 'playlists accesses', 'db_table': 'playlist_access'}>, <CreateModel name='PlaylistVideo', fields=[('id', <django.db.models.fields.AutoField>), ('order', <django.db.models.fields.PositiveIntegerField>), ('playlist', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'playlist video link', 'verbose_name_plural': 'playlist video links', 'db_table': 'playlist_video'}>, <CreateModel name='SignTrack', fields=[('id', <django.db.models.fields.AutoField>), ('language', <django.db.models.fields.CharField>)], options={'verbose_name': 'signs language track', 'verbose_name_plural': 'signs language tracks', 'db_table': 'sign_track'}>, <CreateModel name='SiteAdmin', fields=[('id', <django.db.models.fields.AutoField>), ('site', <django.db.models.fields.related.ForeignKey>), ('user', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'site admin', 'verbose_name_plural': 'site admins', 'db_table': 'site_admin'}>, <CreateModel name='SiteOrganization', fields=[('id', <django.db.models.fields.AutoField>), ('organization', <django.db.models.fields.related.ForeignKey>), ('site', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'organization in site', 'verbose_name_plural': 'organizations in sites', 'db_table': 'site_organization'}>, <CreateModel name='SubtitleTrack', fields=[('id', <django.db.models.fields.AutoField>), ('language', <django.db.models.fields.CharField>), ('has_closed_captioning', <django.db.models.fields.BooleanField>)], options={'verbose_name': 'subtitles track', 'verbose_name_plural': 'subtitles tracks', 'db_table': 'subtitle_track'}>, <CreateModel name='Video', fields=[('id', <django.db.models.fields.AutoField>), ('language', <django.db.models.fields.CharField>), ('author', <django.db.models.fields.related.ForeignKey>), ('duplicated_from', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'video', 'verbose_name_plural': 'videos', 'db_table': 'video'}>, <AddField model_name='subtitletrack', name='video', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='signtrack', name='video', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='playlistvideo', name='video', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='playlist', name='editors', field=<django.db.models.fields.related.ManyToManyField>>, <AddField model_name='playlist', name='organization', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='playlist', name='videos', field=<django.db.models.fields.related.ManyToManyField>>, <AddField model_name='organization', name='managers', field=<django.db.models.fields.related.ManyToManyField>>, <AddField model_name='organization', name='sites', field=<django.db.models.fields.related.ManyToManyField>>, <AddField model_name='consumersite', name='admins', field=<django.db.models.fields.related.ManyToManyField>>, <AddField model_name='authoring', name='organization', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='authoring', name='user', field=<django.db.models.fields.related.ForeignKey>>, <AddField model_name='audiotrack', name='video', field=<django.db.models.fields.related.ForeignKey>>, <AlterUniqueTogether name='subtitletrack', unique_together={('video', 'language', 'has_closed_captioning')}>, <AlterUniqueTogether name='siteorganization', unique_together={('site', 'organization')}>, <AlterUniqueTogether name='siteadmin', unique_together={('user', 'site')}>, <AlterUniqueTogether name='signtrack', unique_together={('video', 'language')}>, <AlterUniqueTogether name='playlistvideo', unique_together={('video', 'playlist')}>, <AlterUniqueTogether name='playlistaccess', unique_together={('user', 'playlist')}>, <AlterUniqueTogether name='organizationmanager', unique_together={('user', 'organization')}>, <AlterUniqueTogether name='authoring', unique_together={('user', 'organization')}>, <AlterUniqueTogether name='audiotrack', unique_together={('video', 'language')}>]¶
-
-
class
marsha.core.migrations.0002_soft_deletion.
Migration
(name, app_label)[source]¶ Bases:
django.db.migrations.migration.Migration
-
dependencies
= [('core', '0001_initial_models')]¶
-
operations
= [<AlterModelManagers name='user', managers=[('objects', <marsha.core.managers.UserManager object>)]>, <AddField model_name='audiotrack', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='authoring', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='consumersite', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='organization', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='organizationmanager', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='playlist', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='playlistaccess', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='playlistvideo', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='signtrack', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='siteadmin', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='siteorganization', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='subtitletrack', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='user', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AddField model_name='video', name='deleted', field=<django.db.models.fields.DateTimeField>>, <AlterField model_name='consumersite', name='name', field=<django.db.models.fields.CharField>>, <AlterField model_name='organization', name='name', field=<django.db.models.fields.CharField>>, <AlterField model_name='playlist', name='author', field=<django.db.models.fields.related.ForeignKey>>, <AlterField model_name='playlist', name='organization', field=<django.db.models.fields.related.ForeignKey>>, <AlterField model_name='video', name='author', field=<django.db.models.fields.related.ForeignKey>>, <AlterUniqueTogether name='audiotrack', unique_together=set()>, <AlterUniqueTogether name='authoring', unique_together=set()>, <AlterUniqueTogether name='organizationmanager', unique_together=set()>, <AlterUniqueTogether name='playlistaccess', unique_together=set()>, <AlterUniqueTogether name='playlistvideo', unique_together=set()>, <AlterUniqueTogether name='signtrack', unique_together=set()>, <AlterUniqueTogether name='siteadmin', unique_together=set()>, <AlterUniqueTogether name='siteorganization', unique_together=set()>, <AlterUniqueTogether name='subtitletrack', unique_together=set()>, <AddIndex model_name='audiotrack', index=<ConditionalUniqueIndex: fields='video, language'>>, <AddIndex model_name='authoring', index=<ConditionalUniqueIndex: fields='user, organization'>>, <AddIndex model_name='organizationmanager', index=<ConditionalUniqueIndex: fields='user, organization'>>, <AddIndex model_name='playlistaccess', index=<ConditionalUniqueIndex: fields='user, playlist'>>, <AddIndex model_name='playlistvideo', index=<ConditionalUniqueIndex: fields='video, playlist'>>, <AddIndex model_name='signtrack', index=<ConditionalUniqueIndex: fields='video, language'>>, <AddIndex model_name='siteadmin', index=<ConditionalUniqueIndex: fields='user, site'>>, <AddIndex model_name='siteorganization', index=<ConditionalUniqueIndex: fields='site, organization'>>, <AddIndex model_name='subtitletrack', index=<ConditionalUniqueIndex: fields='video, language, has_closed_captioning'>>]¶
-
-
class
marsha.core.migrations.0003_missing_text_fields.
Migration
(name, app_label)[source]¶ Bases:
django.db.migrations.migration.Migration
-
dependencies
= [('core', '0002_soft_deletion')]¶
-
operations
= [<AddField model_name='playlist', name='name', field=<django.db.models.fields.CharField>, preserve_default=False>, <AddField model_name='video', name='description', field=<django.db.models.fields.TextField>>, <AddField model_name='video', name='name', field=<django.db.models.fields.CharField>, preserve_default=False>]¶
-
-
class
marsha.core.migrations.0004_duplicated_from__blank.
Migration
(name, app_label)[source]¶ Bases:
django.db.migrations.migration.Migration
-
dependencies
= [('core', '0003_missing_text_fields')]¶
-
operations
= [<AlterField model_name='playlist', name='duplicated_from', field=<django.db.models.fields.related.ForeignKey>>, <AlterField model_name='video', name='duplicated_from', field=<django.db.models.fields.related.ForeignKey>>]¶
-
-
class
marsha.core.migrations.0005_use_our__nondeleteduniqueindex.
Migration
(name, app_label)[source]¶ Bases:
django.db.migrations.migration.Migration
-
dependencies
= [('core', '0004_duplicated_from__blank')]¶
-
operations
= [<RemoveIndex model_name='audiotrack', name='audio_track_video_i_fe6276_idx'>, <RemoveIndex model_name='authoring', name='authoring_user_id_0ce1c4_idx'>, <RemoveIndex model_name='organizationmanager', name='organizatio_user_id_a56b6d_idx'>, <RemoveIndex model_name='playlistaccess', name='playlist_ac_user_id_c7df1b_idx'>, <RemoveIndex model_name='playlistvideo', name='playlist_vi_video_i_6460b7_idx'>, <RemoveIndex model_name='signtrack', name='sign_track_video_i_8ae92b_idx'>, <RemoveIndex model_name='siteadmin', name='site_admin_user_id_62a0e6_idx'>, <RemoveIndex model_name='siteorganization', name='site_organi_site_id_f51dca_idx'>, <RemoveIndex model_name='subtitletrack', name='subtitle_tr_video_i_7ef2a4_idx'>, <AddIndex model_name='audiotrack', index=<NonDeletedUniqueIndex: fields='video, language'>>, <AddIndex model_name='authoring', index=<NonDeletedUniqueIndex: fields='user, organization'>>, <AddIndex model_name='organizationmanager', index=<NonDeletedUniqueIndex: fields='user, organization'>>, <AddIndex model_name='playlistaccess', index=<NonDeletedUniqueIndex: fields='user, playlist'>>, <AddIndex model_name='playlistvideo', index=<NonDeletedUniqueIndex: fields='video, playlist'>>, <AddIndex model_name='signtrack', index=<NonDeletedUniqueIndex: fields='video, language'>>, <AddIndex model_name='siteadmin', index=<NonDeletedUniqueIndex: fields='user, site'>>, <AddIndex model_name='siteorganization', index=<NonDeletedUniqueIndex: fields='site, organization'>>, <AddIndex model_name='subtitletrack', index=<NonDeletedUniqueIndex: fields='video, language, has_closed_captioning'>>]¶
-
Submodules¶
marsha.core.admin module¶
Admin of the core
app of the Marsha project.
-
class
marsha.core.admin.
AudioTrackInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for audio tracks of a video.
-
media
¶
-
model
¶ alias of
marsha.core.models.AudioTrack
-
-
class
marsha.core.admin.
AuthorOrganizationsInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for organizations the user is an author of.
-
media
¶
-
model
¶ alias of
marsha.core.models.Authoring
-
verbose_name
= 'authoring organization'¶
-
verbose_name_plural
= 'authoring organizations'¶
-
-
class
marsha.core.admin.
BaseModelAdmin
(model, admin_site)[source]¶ Bases:
safedelete.admin.SafeDeleteAdmin
Base for all our model admins.
-
media
¶
-
-
class
marsha.core.admin.
BaseTabularInline
(parent_model, admin_site)[source]¶ Bases:
django.contrib.admin.options.TabularInline
Base for all our tabular inlines.
-
media
¶
-
-
class
marsha.core.admin.
ConsumerSiteAdmin
(model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseModelAdmin
Admin class for the ConsumerSite model.
-
inlines
= [<class 'marsha.core.admin.SiteAdminsInline'>, <class 'marsha.core.admin.SiteOrganizationsInline'>]¶
-
list_display
= ('name',)¶
-
media
¶
-
-
class
marsha.core.admin.
ManagedOrganizationsInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for organizations managed by a user.
-
media
¶
-
model
¶
-
verbose_name
= 'managed organization'¶
-
verbose_name_plural
= 'managed organizations'¶
-
-
class
marsha.core.admin.
MarshaAdminSite
(name='admin')[source]¶ Bases:
django.contrib.admin.sites.AdminSite
Admin site for Marsha.
-
site_header
= 'Marsha'¶
-
site_title
= 'Marsha administration'¶
-
-
class
marsha.core.admin.
OrganizationAdmin
(model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseModelAdmin
Admin class for the Organization model.
-
inlines
= [<class 'marsha.core.admin.OrganizationManagersInline'>, <class 'marsha.core.admin.OrganizationSitesInline'>, <class 'marsha.core.admin.OrganizationAuthorsInline'>]¶
-
list_display
= ('name',)¶
-
media
¶
-
-
class
marsha.core.admin.
OrganizationAuthorsInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for authors in an organization.
-
media
¶
-
model
¶ alias of
marsha.core.models.Authoring
-
verbose_name
= 'author'¶
-
verbose_name_plural
= 'authors'¶
-
-
class
marsha.core.admin.
OrganizationManagersInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for managers in an organization.
-
media
¶
-
model
¶
-
verbose_name
= 'manager'¶
-
verbose_name_plural
= 'managers'¶
-
-
class
marsha.core.admin.
OrganizationSitesInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for sites for an organization.
-
media
¶
-
model
¶ alias of
marsha.core.models.SiteOrganization
-
verbose_name
= 'site'¶
-
verbose_name_plural
= 'sites'¶
-
-
class
marsha.core.admin.
PlaylistAdmin
(model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseModelAdmin
Admin class for the Playlist model.
-
exclude
= ('duplicated_from',)¶
-
inlines
= [<class 'marsha.core.admin.PlaylistVideosInline'>, <class 'marsha.core.admin.PlaystlistAccessesInline'>]¶
-
list_display
= ('name', 'organization', 'author', 'is_public')¶
-
media
¶
-
-
class
marsha.core.admin.
PlaylistVideosInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for videos in a playlist.
-
media
¶
-
model
¶ alias of
marsha.core.models.PlaylistVideo
-
verbose_name
= 'video'¶
-
verbose_name_plural
= 'videos'¶
-
-
class
marsha.core.admin.
PlaystlistAccessesInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for with right to write access to a playlist.
-
media
¶
-
model
¶ alias of
marsha.core.models.PlaylistAccess
-
verbose_name
= 'user access'¶
-
verbose_name_plural
= 'users accesses'¶
-
-
class
marsha.core.admin.
SignTrackInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for sign tracks of a video.
-
media
¶
-
model
¶ alias of
marsha.core.models.SignTrack
-
-
class
marsha.core.admin.
SiteAdminsInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for admins of a site.
-
media
¶
-
model
¶ alias of
marsha.core.models.SiteAdmin
-
verbose_name
= 'admin'¶
-
verbose_name_plural
= 'admins'¶
-
-
class
marsha.core.admin.
SiteOrganizationsInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for organizations in a site.
-
media
¶
-
model
¶ alias of
marsha.core.models.SiteOrganization
-
verbose_name
= 'organization'¶
-
verbose_name_plural
= 'organizations'¶
-
-
class
marsha.core.admin.
SubtitleTrackInline
(parent_model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseTabularInline
Inline for subtitle tracks of a video.
-
media
¶
-
model
¶ alias of
marsha.core.models.SubtitleTrack
-
-
class
marsha.core.admin.
UserAdmin
(model, admin_site)[source]¶ Bases:
django.contrib.auth.admin.UserAdmin
Admin class for the User model.
-
inlines
= [<class 'marsha.core.admin.ManagedOrganizationsInline'>, <class 'marsha.core.admin.AuthorOrganizationsInline'>]¶
-
media
¶
-
-
class
marsha.core.admin.
VideoAdmin
(model, admin_site)[source]¶ Bases:
marsha.core.admin.BaseModelAdmin
Admin class for the Video model.
-
exclude
= ('duplicated_from',)¶
-
inlines
= [<class 'marsha.core.admin.AudioTrackInline'>, <class 'marsha.core.admin.SubtitleTrackInline'>, <class 'marsha.core.admin.SignTrackInline'>]¶
-
list_display
= ('name', 'author', 'language')¶
-
media
¶
-
marsha.core.apps module¶
Defines the django app config for the core
app.
marsha.core.base_models module¶
Base models for the core app of the Marsha project.
-
class
marsha.core.base_models.
BaseModel
(*args, **kwargs)[source]¶ Bases:
safedelete.models.SafeDeleteModel
Base model for all our models.
It is based on
SafeDeleteModel
to easily manage how we want the instances to be deleted/soft-deleted, with or without its relationships. The defaultsafedelete
policy isSOFT_DELETE_CASCADE
, ie the object to delete and its relations will be soft deleted: theirdeleted
field will be filled with the current date-time (the opposite,None
, is the same as “not deleted”)- Also it adds some checks run with
django check
: - check that all fields are correctly annotated.
- same for fields pointing to other models: final models must have all related
names properly annotated. - check that every
ManyToManyField
use a definedthrough
table. - check that every model have adb_table
defined, not prefixed with the name of the app or the project.
Parameters: deleted (DateTimeField) – Deleted -
classmethod
check
(**kwargs) → List[django.core.checks.messages.CheckMessage][source]¶ Add checks for related names.
Parameters: kwargs (Any) – Actually not used but asked by django to be present “for possible future usage”. Returns: A list of the check messages representing problems found on the model. Return type: List[checks.CheckMessage]
- Also it adds some checks run with
-
class
marsha.core.base_models.
NonDeletedUniqueIndex
(fields: Sequence, name: str = None) → None[source]¶ Bases:
psqlextra.indexes.conditional_unique_index.ConditionalUniqueIndex
A special ConditionalUniqueIndex for non deleted objects.
-
__init__
(fields: Sequence, name: str = None) → None[source]¶ Override default init to pass our predefined condition.
For the parameters, see
ConditionalUniqueIndex.__init__
.
-
condition
= '"deleted" IS NULL'¶
-
marsha.core.managers module¶
This module holds the managers for the marsha models.
marsha.core.models module¶
This module holds the models for the marsha project.
-
class
marsha.core.models.
AudioTrack
(*args, **kwargs)[source]¶ Bases:
marsha.core.models.BaseTrack
Model representing an additional audio track for a video.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- video (ForeignKey to
Video
) – video for which this track is - language (CharField) – language of this track
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
get_language_display
(*, field=<django.db.models.fields.CharField: language>)¶ Autogenerated: Shows the label of the
language
-
id
¶ Model field: ID
-
class
marsha.core.models.
Authoring
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing authors in an organization.
through
model betweenOrganization.authors
andUser.authoring
.Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- user (ForeignKey to
User
) – user having authoring access in this organization - organization (ForeignKey to
Organization
) – organization on which the user is an author
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
organization
¶ Model field: organization, accesses the
Organization
model.
-
organization_id
¶ Model field: organization
-
user_id
¶ Model field: author
-
class
marsha.core.models.
BaseTrack
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Base model for different kinds of tracks tied to a video.
Parameters: - deleted (DateTimeField) – Deleted
- video (ForeignKey to
Video
) – video for which this track is - language (CharField) – language of this track
-
get_language_display
(*, field=<django.db.models.fields.CharField: language>)¶ Autogenerated: Shows the label of the
language
-
language
¶ Model field: track language
-
video_id
¶ Model field: video
-
class
marsha.core.models.
ConsumerSite
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing an external site with access to the Marsha instance.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- name (CharField) – Name of the site
- admins (ManyToManyField) – users able to manage this site
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
admins
¶ Model field: administrators, accesses the M2M
ConsumerSite
model.
-
id
¶ Model field: ID
-
name
¶ Model field: name
-
organizations
¶ Model field: sites, accesses the M2M
Organization
model.
-
organizations_links
¶ Model field: site, accesses the M2M
SiteOrganization
model.
-
class
marsha.core.models.
Organization
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing an organization to manage its playlists on one or many sites.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- name (CharField) – name of the organization
- sites (ManyToManyField) – sites where this organization is present
- managers (ManyToManyField) – users able to manage this organization
- authors (ManyToManyField) – users able to manage playlists in this organization
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
Model field: organization, accesses the M2M
Authoring
model.
Model field: authors, accesses the M2M
Organization
model.
-
id
¶ Model field: ID
-
managers
¶ Model field: managers, accesses the M2M
Organization
model.
-
managers_links
¶ Model field: organization, accesses the M2M
OrganizationManager
model.
-
name
¶ Model field: name
-
sites
¶ Model field: sites, accesses the M2M
Organization
model.
-
sites_links
¶ Model field: organization, accesses the M2M
SiteOrganization
model.
-
class
marsha.core.models.
OrganizationManager
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing managers of organizations.
through
model betweenOrganization.managers
andUser.managed_organizations
.Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- user (ForeignKey to
User
) – user managing this organization - organization (ForeignKey to
Organization
) – organization managed by this user
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
organization
¶ Model field: organization, accesses the
Organization
model.
-
organization_id
¶ Model field: organization
-
user_id
¶ Model field: manager
-
class
marsha.core.models.
Playlist
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing a playlist which is a list of videos.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- name (CharField) – name of the playlist
- organization (ForeignKey to
Organization
) – Organization - author (ForeignKey to
User
) – Author - is_public (BooleanField) – if this playlist can be viewed without any access control
- duplicated_from (ForeignKey to
Playlist
) – original playlist this one was duplicated from - editors (ManyToManyField) – users allowed to manage this playlist
- videos (ManyToManyField) – videos in this playlist
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
Model field: author, accesses the
User
model.
Model field: author
-
duplicated_from_id
¶ Model field: duplicate from
-
id
¶ Model field: ID
-
is_public
¶ Model field: is public
-
name
¶ Model field: name
-
organization
¶ Model field: organization, accesses the
Organization
model.
-
organization_id
¶ Model field: organization
-
users_accesses
¶ Model field: playlist, accesses the M2M
PlaylistAccess
model.
-
videos_links
¶ Model field: playlist, accesses the M2M
PlaylistVideo
model.
-
class
marsha.core.models.
PlaylistAccess
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing a user having right to manage a playlist.
through
model betweenPlaylist.editors
andUser.managed_playlists
.Parameters: -
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
playlist_id
¶ Model field: playlist
-
user_id
¶ Model field: user
-
exception
-
class
marsha.core.models.
PlaylistVideo
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing a video in a playlist.
through
model betweenPlaylist.videos
andVideo.playlists
.Parameters: -
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
order
¶ Model field: order
-
playlist_id
¶ Model field: playlist
-
video_id
¶ Model field: video
-
exception
-
class
marsha.core.models.
SignTrack
(*args, **kwargs)[source]¶ Bases:
marsha.core.models.BaseTrack
Model representing a signs language track for a video.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- video (ForeignKey to
Video
) – video for which this track is - language (CharField) – language of this track
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
get_language_display
(*, field=<django.db.models.fields.CharField: language>)¶ Autogenerated: Shows the label of the
language
-
id
¶ Model field: ID
-
class
marsha.core.models.
SiteAdmin
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing users with access to manage a site.
through
model betweenConsumerSite.admins
andUser.administrated_sites
.Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- user (ForeignKey to
User
) – user with access to the site - site (ForeignKey to
ConsumerSite
) – site to which the user has access
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
site
¶ Model field: site, accesses the
ConsumerSite
model.
-
site_id
¶ Model field: site
-
user_id
¶ Model field: user
-
class
marsha.core.models.
SiteOrganization
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing organizations in sites.
through
model betweenOrganization.sites
andConsumerSite.organizations
.Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- site (ForeignKey to
ConsumerSite
) – site having this organization - organization (ForeignKey to
Organization
) – organization in this site
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
id
¶ Model field: ID
-
organization
¶ Model field: organization, accesses the
Organization
model.
-
organization_id
¶ Model field: organization
-
site
¶ Model field: site, accesses the
ConsumerSite
model.
-
site_id
¶ Model field: site
-
class
marsha.core.models.
SubtitleTrack
(*args, **kwargs)[source]¶ Bases:
marsha.core.models.BaseTrack
Model representing a subtitle track for a video.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- video (ForeignKey to
Video
) – video for which this track is - language (CharField) – language of this track
- has_closed_captioning (BooleanField) – if closed captioning (for death or hard of hearing viewers) is on for this subtitle track
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
get_language_display
(*, field=<django.db.models.fields.CharField: language>)¶ Autogenerated: Shows the label of the
language
-
has_closed_captioning
¶ Model field: closed captioning
-
id
¶ Model field: ID
-
class
marsha.core.models.
User
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
,django.contrib.auth.models.AbstractUser
Model representing a user that can be authenticated to act on the Marsha instance.
Parameters: - id (AutoField) – Id
- password (CharField) – Password
- last_login (DateTimeField) – Last login
- is_superuser (BooleanField) – Designates that this user has all permissions without explicitly assigning them.
- username (CharField) – Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.
- first_name (CharField) – First name
- last_name (CharField) – Last name
- email (EmailField) – Email address
- is_staff (BooleanField) – Designates whether the user can log into this admin site.
- is_active (BooleanField) – Designates whether this user should be treated as active. Unselect this instead of deleting accounts.
- date_joined (DateTimeField) – Date joined
- deleted (DateTimeField) – Deleted
- groups (ManyToManyField) – The groups this user belongs to. A user will get all permissions granted to each of their groups.
- user_permissions (ManyToManyField) – Specific permissions for this user.
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
administrated_sites
¶ Model field: administrators, accesses the M2M
ConsumerSite
model.
Model field: authors, accesses the M2M
Organization
model.
Model field: author, accesses the M2M
Video
model.
Model field: author, accesses the M2M
Authoring
model.
-
get_next_by_date_joined
(*, field=<django.db.models.fields.DateTimeField: date_joined>, is_next=True, **kwargs)¶ Autogenerated: Finds next instance based on
date_joined
.
-
get_previous_by_date_joined
(*, field=<django.db.models.fields.DateTimeField: date_joined>, is_next=False, **kwargs)¶ Autogenerated: Finds previous instance based on
date_joined
.
-
id
¶ Model field: ID
-
logentry_set
¶ Model field: user, accesses the M2M
LogEntry
model.
-
managed_organizations
¶ Model field: managers, accesses the M2M
Organization
model.
-
managed_organizations_links
¶ Model field: manager, accesses the M2M
OrganizationManager
model.
-
objects
= <marsha.core.managers.UserManager object>¶
-
playlists_accesses
¶ Model field: user, accesses the M2M
PlaylistAccess
model.
-
class
marsha.core.models.
Video
(*args, **kwargs)[source]¶ Bases:
marsha.core.base_models.BaseModel
Model representing a video, by an author.
Parameters: - id (AutoField) – Id
- deleted (DateTimeField) – Deleted
- name (CharField) – name of the video
- description (TextField) – description of the video
- author (ForeignKey to
User
) – author of the video - language (CharField) – language of the video
- duplicated_from (ForeignKey to
Video
) – original video this one was duplicated from
-
exception
DoesNotExist
¶ Bases:
django.core.exceptions.ObjectDoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
django.core.exceptions.MultipleObjectsReturned
-
audiotracks
¶ Model field: video, accesses the M2M
AudioTrack
model.
Model field: author, accesses the
User
model.
Model field: author
-
description
¶ Model field: description
-
duplicated_from_id
¶ Model field: duplicate from
-
get_language_display
(*, field=<django.db.models.fields.CharField: language>)¶ Autogenerated: Shows the label of the
language
-
id
¶ Model field: ID
-
language
¶ Model field: language
-
name
¶ Model field: name
-
playlists_links
¶ Model field: video, accesses the M2M
PlaylistVideo
model.
-
subtitletracks
¶ Model field: video, accesses the M2M
SubtitleTrack
model.
marsha.core.views module¶
Views of the core
app of the Marsha project.
Module contents¶
The core
app of the Marsha project.
Submodules¶
marsha.settings module¶
Django settings for marsha project.
Uses django-configurations to manage environments inheritance and the loading of some config from the environment
-
class
marsha.settings.
Base
[source]¶ Bases:
configurations.base.Configuration
Base configuration every configuration (aka environment) should inherit from.
It depends on an environment variable that SHOULD be defined: - DJANGO_SECRET_KEY
You may also want to override default configuration by setting the following environment variables: - DJANGO_DEBUG - DATABASE_URL
-
ABSOLUTE_URL_OVERRIDES
= {}¶
-
ADMINS
= []¶
-
ALLOWED_HOSTS
= []¶
-
APPEND_SLASH
= True¶
-
AUTHENTICATION_BACKENDS
= ['django.contrib.auth.backends.ModelBackend']¶
-
AUTH_PASSWORD_VALIDATORS
= [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}]¶
-
AUTH_USER_MODEL
= 'core.User'¶
-
BASE_DIR
= '/home/docs/checkouts/readthedocs.org/user_builds/marsha/envs/latest/lib/python3.6/site-packages/marsha'¶
-
CACHES
= {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}¶
-
CACHE_MIDDLEWARE_ALIAS
= 'default'¶
-
CACHE_MIDDLEWARE_KEY_PREFIX
= ''¶
-
CACHE_MIDDLEWARE_SECONDS
= 600¶
-
CSRF_COOKIE_AGE
= 31449600¶
-
CSRF_COOKIE_DOMAIN
= None¶
-
CSRF_COOKIE_HTTPONLY
= False¶
-
CSRF_COOKIE_NAME
= 'csrftoken'¶
-
CSRF_COOKIE_PATH
= '/'¶
-
CSRF_COOKIE_SECURE
= False¶
-
CSRF_FAILURE_VIEW
= 'django.views.csrf.csrf_failure'¶
-
CSRF_HEADER_NAME
= 'HTTP_X_CSRFTOKEN'¶
-
CSRF_TRUSTED_ORIGINS
= []¶
-
CSRF_USE_SESSIONS
= False¶
-
DATABASES
= {}¶
-
DATABASE_ROUTERS
= []¶
-
DATA_UPLOAD_MAX_MEMORY_SIZE
= 2621440¶
-
DATA_UPLOAD_MAX_NUMBER_FIELDS
= 1000¶
-
DATETIME_FORMAT
= 'N j, Y, P'¶
-
DATETIME_INPUT_FORMATS
= ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%Y', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M', '%m/%d/%y']¶
-
DATE_FORMAT
= 'N j, Y'¶
-
DATE_INPUT_FORMATS
= ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y']¶
-
DEBUG
= False¶
-
DEBUG_PROPAGATE_EXCEPTIONS
= False¶
-
DECIMAL_SEPARATOR
= '.'¶
-
DEFAULT_CHARSET
= 'utf-8'¶
-
DEFAULT_CONTENT_TYPE
= 'text/html'¶
-
DEFAULT_EXCEPTION_REPORTER_FILTER
= 'django.views.debug.SafeExceptionReporterFilter'¶
-
DEFAULT_FILE_STORAGE
= 'django.core.files.storage.FileSystemStorage'¶
-
DEFAULT_FROM_EMAIL
= 'webmaster@localhost'¶
-
DEFAULT_INDEX_TABLESPACE
= ''¶
-
DEFAULT_TABLESPACE
= ''¶
-
DISALLOWED_USER_AGENTS
= []¶
-
DOTENV_LOADED
= None¶
-
EMAIL_BACKEND
= 'django.core.mail.backends.smtp.EmailBackend'¶
-
EMAIL_HOST
= 'localhost'¶
-
EMAIL_HOST_PASSWORD
= ''¶
-
EMAIL_HOST_USER
= ''¶
-
EMAIL_PORT
= 25¶
-
EMAIL_SSL_CERTFILE
= None¶
-
EMAIL_SSL_KEYFILE
= None¶
-
EMAIL_SUBJECT_PREFIX
= '[Django] '¶
-
EMAIL_TIMEOUT
= None¶
-
EMAIL_USE_LOCALTIME
= False¶
-
EMAIL_USE_SSL
= False¶
-
EMAIL_USE_TLS
= False¶
-
FILE_CHARSET
= 'utf-8'¶
-
FILE_UPLOAD_DIRECTORY_PERMISSIONS
= None¶
-
FILE_UPLOAD_HANDLERS
= ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler']¶
-
FILE_UPLOAD_MAX_MEMORY_SIZE
= 2621440¶
-
FILE_UPLOAD_PERMISSIONS
= None¶
-
FILE_UPLOAD_TEMP_DIR
= None¶
-
FIRST_DAY_OF_WEEK
= 0¶
-
FIXTURE_DIRS
= []¶
-
FORCE_SCRIPT_NAME
= None¶
-
FORMAT_MODULE_PATH
= None¶
-
FORM_RENDERER
= 'django.forms.renderers.DjangoTemplates'¶
-
IGNORABLE_404_URLS
= []¶
-
INSTALLED_APPS
= ['django.contrib.admin.apps.SimpleAdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', 'marsha.core.apps.CoreConfig']¶
-
INTERNAL_IPS
= []¶
-
LANGUAGES
= [('en', 'english'), ('fr', 'french')]¶
-
LANGUAGES_BIDI
= ['he', 'ar', 'fa', 'ur']¶
-
LANGUAGE_CODE
= 'en-us'¶
-
LANGUAGE_COOKIE_AGE
= None¶
-
LANGUAGE_COOKIE_DOMAIN
= None¶
-
LANGUAGE_COOKIE_NAME
= 'django_language'¶
-
LANGUAGE_COOKIE_PATH
= '/'¶
-
LOCALE_PATHS
= []¶
-
LOGGING
= {}¶
-
LOGGING_CONFIG
= 'logging.config.dictConfig'¶
-
LOGIN_REDIRECT_URL
= '/accounts/profile/'¶
-
LOGIN_URL
= '/accounts/login/'¶
-
LOGOUT_REDIRECT_URL
= None¶
-
MANAGERS
= []¶
-
MEDIA_ROOT
= ''¶
-
MEDIA_URL
= ''¶
-
MESSAGE_STORAGE
= 'django.contrib.messages.storage.fallback.FallbackStorage'¶
-
MIDDLEWARE
= ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware']¶
-
MIGRATION_MODULES
= {}¶
-
MONTH_DAY_FORMAT
= 'F j'¶
-
NUMBER_GROUPING
= 0¶
-
PASSWORD_HASHERS
= ['django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.BCryptPasswordHasher']¶
-
PASSWORD_RESET_TIMEOUT_DAYS
= 3¶
-
PREPEND_WWW
= False¶
-
ROOT_URLCONF
= 'marsha.urls'¶
-
SECRET_KEY
= 'FooBar'¶
-
SECURE_BROWSER_XSS_FILTER
= False¶
-
SECURE_CONTENT_TYPE_NOSNIFF
= False¶
-
SECURE_HSTS_INCLUDE_SUBDOMAINS
= False¶
-
SECURE_HSTS_PRELOAD
= False¶
-
SECURE_HSTS_SECONDS
= 0¶
-
SECURE_PROXY_SSL_HEADER
= None¶
-
SECURE_REDIRECT_EXEMPT
= []¶
-
SECURE_SSL_HOST
= None¶
-
SECURE_SSL_REDIRECT
= False¶
-
SERVER_EMAIL
= 'root@localhost'¶
-
SESSION_CACHE_ALIAS
= 'default'¶
-
SESSION_COOKIE_AGE
= 1209600¶
-
SESSION_COOKIE_DOMAIN
= None¶
-
SESSION_COOKIE_HTTPONLY
= True¶
-
SESSION_COOKIE_NAME
= 'sessionid'¶
-
SESSION_COOKIE_PATH
= '/'¶
-
SESSION_COOKIE_SECURE
= False¶
-
SESSION_ENGINE
= 'django.contrib.sessions.backends.db'¶
-
SESSION_EXPIRE_AT_BROWSER_CLOSE
= False¶
-
SESSION_FILE_PATH
= None¶
-
SESSION_SAVE_EVERY_REQUEST
= False¶
-
SESSION_SERIALIZER
= 'django.contrib.sessions.serializers.JSONSerializer'¶
-
SHORT_DATETIME_FORMAT
= 'm/d/Y P'¶
-
SHORT_DATE_FORMAT
= 'm/d/Y'¶
-
SIGNING_BACKEND
= 'django.core.signing.TimestampSigner'¶
-
SILENCED_SYSTEM_CHECKS
= []¶
-
STATICFILES_DIRS
= []¶
-
STATICFILES_FINDERS
= ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder']¶
-
STATICFILES_STORAGE
= 'django.contrib.staticfiles.storage.StaticFilesStorage'¶
-
STATIC_ROOT
= None¶
-
STATIC_URL
= '/static/'¶
-
TEMPLATES
= [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages']}}]¶
-
TEST_NON_SERIALIZED_APPS
= []¶
-
TEST_RUNNER
= 'django.test.runner.DiscoverRunner'¶
-
THOUSAND_SEPARATOR
= ','¶
-
TIME_FORMAT
= 'P'¶
-
TIME_INPUT_FORMATS
= ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']¶
-
TIME_ZONE
= 'UTC'¶
-
USE_ETAGS
= False¶
-
USE_I18N
= True¶
-
USE_L10N
= True¶
-
USE_THOUSAND_SEPARATOR
= False¶
-
USE_TZ
= True¶
-
USE_X_FORWARDED_HOST
= False¶
-
USE_X_FORWARDED_PORT
= False¶
-
WSGI_APPLICATION
= 'marsha.wsgi.application'¶
-
X_FRAME_OPTIONS
= 'SAMEORIGIN'¶
-
YEAR_MONTH_FORMAT
= 'F Y'¶
-
-
class
marsha.settings.
Dev
[source]¶ Bases:
marsha.settings.Base
Development environment settings.
We set
DEBUG
toTrue
by default, configure the server to respond to all hosts, and use a local sqlite database by default.-
ABSOLUTE_URL_OVERRIDES
= {}¶
-
ADMINS
= []¶
-
ALLOWED_HOSTS
= ['*']¶
-
APPEND_SLASH
= True¶
-
AUTHENTICATION_BACKENDS
= ['django.contrib.auth.backends.ModelBackend']¶
-
AUTH_PASSWORD_VALIDATORS
= [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}]¶
-
AUTH_USER_MODEL
= 'core.User'¶
-
BASE_DIR
= '/home/docs/checkouts/readthedocs.org/user_builds/marsha/envs/latest/lib/python3.6/site-packages/marsha'¶
-
CACHES
= {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}¶
-
CACHE_MIDDLEWARE_ALIAS
= 'default'¶
-
CACHE_MIDDLEWARE_KEY_PREFIX
= ''¶
-
CACHE_MIDDLEWARE_SECONDS
= 600¶
-
CSRF_COOKIE_AGE
= 31449600¶
-
CSRF_COOKIE_DOMAIN
= None¶
-
CSRF_COOKIE_HTTPONLY
= False¶
-
CSRF_COOKIE_NAME
= 'csrftoken'¶
-
CSRF_COOKIE_PATH
= '/'¶
-
CSRF_COOKIE_SECURE
= False¶
-
CSRF_FAILURE_VIEW
= 'django.views.csrf.csrf_failure'¶
-
CSRF_HEADER_NAME
= 'HTTP_X_CSRFTOKEN'¶
-
CSRF_TRUSTED_ORIGINS
= []¶
-
CSRF_USE_SESSIONS
= False¶
-
DATABASES
= {'default': {'NAME': '/home/docs/checkouts/readthedocs.org/user_builds/marsha/envs/latest/lib/python3.6/site-packages/marsha/db.sqlite3', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.sqlite3', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}}}¶
-
DATABASE_ROUTERS
= []¶
-
DATA_UPLOAD_MAX_MEMORY_SIZE
= 2621440¶
-
DATA_UPLOAD_MAX_NUMBER_FIELDS
= 1000¶
-
DATETIME_FORMAT
= 'N j, Y, P'¶
-
DATETIME_INPUT_FORMATS
= ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%Y', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M', '%m/%d/%y']¶
-
DATE_FORMAT
= 'N j, Y'¶
-
DATE_INPUT_FORMATS
= ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y']¶
-
DEBUG
= False¶
-
DEBUG_PROPAGATE_EXCEPTIONS
= False¶
-
DECIMAL_SEPARATOR
= '.'¶
-
DEFAULT_CHARSET
= 'utf-8'¶
-
DEFAULT_CONTENT_TYPE
= 'text/html'¶
-
DEFAULT_EXCEPTION_REPORTER_FILTER
= 'django.views.debug.SafeExceptionReporterFilter'¶
-
DEFAULT_FILE_STORAGE
= 'django.core.files.storage.FileSystemStorage'¶
-
DEFAULT_FROM_EMAIL
= 'webmaster@localhost'¶
-
DEFAULT_INDEX_TABLESPACE
= ''¶
-
DEFAULT_TABLESPACE
= ''¶
-
DISALLOWED_USER_AGENTS
= []¶
-
DOTENV_LOADED
= None¶
-
EMAIL_BACKEND
= 'django.core.mail.backends.smtp.EmailBackend'¶
-
EMAIL_HOST
= 'localhost'¶
-
EMAIL_HOST_PASSWORD
= ''¶
-
EMAIL_HOST_USER
= ''¶
-
EMAIL_PORT
= 25¶
-
EMAIL_SSL_CERTFILE
= None¶
-
EMAIL_SSL_KEYFILE
= None¶
-
EMAIL_SUBJECT_PREFIX
= '[Django] '¶
-
EMAIL_TIMEOUT
= None¶
-
EMAIL_USE_LOCALTIME
= False¶
-
EMAIL_USE_SSL
= False¶
-
EMAIL_USE_TLS
= False¶
-
FILE_CHARSET
= 'utf-8'¶
-
FILE_UPLOAD_DIRECTORY_PERMISSIONS
= None¶
-
FILE_UPLOAD_HANDLERS
= ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler']¶
-
FILE_UPLOAD_MAX_MEMORY_SIZE
= 2621440¶
-
FILE_UPLOAD_PERMISSIONS
= None¶
-
FILE_UPLOAD_TEMP_DIR
= None¶
-
FIRST_DAY_OF_WEEK
= 0¶
-
FIXTURE_DIRS
= []¶
-
FORCE_SCRIPT_NAME
= None¶
-
FORMAT_MODULE_PATH
= None¶
-
FORM_RENDERER
= 'django.forms.renderers.DjangoTemplates'¶
-
IGNORABLE_404_URLS
= []¶
-
INSTALLED_APPS
= ['django.contrib.admin.apps.SimpleAdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', 'marsha.core.apps.CoreConfig']¶
-
INTERNAL_IPS
= []¶
-
LANGUAGES
= [('en', 'english'), ('fr', 'french')]¶
-
LANGUAGES_BIDI
= ['he', 'ar', 'fa', 'ur']¶
-
LANGUAGE_CODE
= 'en-us'¶
-
LANGUAGE_COOKIE_AGE
= None¶
-
LANGUAGE_COOKIE_DOMAIN
= None¶
-
LANGUAGE_COOKIE_NAME
= 'django_language'¶
-
LANGUAGE_COOKIE_PATH
= '/'¶
-
LOCALE_PATHS
= []¶
-
LOGGING
= {}¶
-
LOGGING_CONFIG
= 'logging.config.dictConfig'¶
-
LOGIN_REDIRECT_URL
= '/accounts/profile/'¶
-
LOGIN_URL
= '/accounts/login/'¶
-
LOGOUT_REDIRECT_URL
= None¶
-
MANAGERS
= []¶
-
MEDIA_ROOT
= ''¶
-
MEDIA_URL
= ''¶
-
MESSAGE_STORAGE
= 'django.contrib.messages.storage.fallback.FallbackStorage'¶
-
MIDDLEWARE
= ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware']¶
-
MIGRATION_MODULES
= {}¶
-
MONTH_DAY_FORMAT
= 'F j'¶
-
NUMBER_GROUPING
= 0¶
-
PASSWORD_HASHERS
= ['django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.BCryptPasswordHasher']¶
-
PASSWORD_RESET_TIMEOUT_DAYS
= 3¶
-
PREPEND_WWW
= False¶
-
ROOT_URLCONF
= 'marsha.urls'¶
-
SECRET_KEY
= 'FooBar'¶
-
SECURE_BROWSER_XSS_FILTER
= False¶
-
SECURE_CONTENT_TYPE_NOSNIFF
= False¶
-
SECURE_HSTS_INCLUDE_SUBDOMAINS
= False¶
-
SECURE_HSTS_PRELOAD
= False¶
-
SECURE_HSTS_SECONDS
= 0¶
-
SECURE_PROXY_SSL_HEADER
= None¶
-
SECURE_REDIRECT_EXEMPT
= []¶
-
SECURE_SSL_HOST
= None¶
-
SECURE_SSL_REDIRECT
= False¶
-
SERVER_EMAIL
= 'root@localhost'¶
-
SESSION_CACHE_ALIAS
= 'default'¶
-
SESSION_COOKIE_AGE
= 1209600¶
-
SESSION_COOKIE_DOMAIN
= None¶
-
SESSION_COOKIE_HTTPONLY
= True¶
-
SESSION_COOKIE_NAME
= 'sessionid'¶
-
SESSION_COOKIE_PATH
= '/'¶
-
SESSION_COOKIE_SECURE
= False¶
-
SESSION_ENGINE
= 'django.contrib.sessions.backends.db'¶
-
SESSION_EXPIRE_AT_BROWSER_CLOSE
= False¶
-
SESSION_FILE_PATH
= None¶
-
SESSION_SAVE_EVERY_REQUEST
= False¶
-
SESSION_SERIALIZER
= 'django.contrib.sessions.serializers.JSONSerializer'¶
-
SHORT_DATETIME_FORMAT
= 'm/d/Y P'¶
-
SHORT_DATE_FORMAT
= 'm/d/Y'¶
-
SIGNING_BACKEND
= 'django.core.signing.TimestampSigner'¶
-
SILENCED_SYSTEM_CHECKS
= []¶
-
STATICFILES_DIRS
= []¶
-
STATICFILES_FINDERS
= ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder']¶
-
STATICFILES_STORAGE
= 'django.contrib.staticfiles.storage.StaticFilesStorage'¶
-
STATIC_ROOT
= None¶
-
STATIC_URL
= '/static/'¶
-
TEMPLATES
= [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages']}}]¶
-
TEST_NON_SERIALIZED_APPS
= []¶
-
TEST_RUNNER
= 'django.test.runner.DiscoverRunner'¶
-
THOUSAND_SEPARATOR
= ','¶
-
TIME_FORMAT
= 'P'¶
-
TIME_INPUT_FORMATS
= ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']¶
-
TIME_ZONE
= 'UTC'¶
-
USE_ETAGS
= False¶
-
USE_I18N
= True¶
-
USE_L10N
= True¶
-
USE_THOUSAND_SEPARATOR
= False¶
-
USE_TZ
= True¶
-
USE_X_FORWARDED_HOST
= False¶
-
USE_X_FORWARDED_PORT
= False¶
-
WSGI_APPLICATION
= 'marsha.wsgi.application'¶
-
X_FRAME_OPTIONS
= 'SAMEORIGIN'¶
-
YEAR_MONTH_FORMAT
= 'F Y'¶
-
marsha.stubs module¶
Stubs for the whole project to be used for typing annotations.
-
class
marsha.stubs.
M2MType
[source]¶ Bases:
typing.Generic
Stub to represent both sides of a django
ManyToManyField
.
-
class
marsha.stubs.
ReverseFKType
[source]¶ Bases:
typing.Generic
Stub to represent the related field of a django
ForeignKey
/OneToOneField
.
-
marsha.stubs.
ReverseO2O
¶ alias of
marsha.stubs.ReverseFKType
marsha.test_runner module¶
Provides a test-runner to avoid running django checks.
-
class
marsha.test_runner.
NoCheckDiscoverRunner
(pattern=None, top_level=None, verbosity=1, interactive=True, failfast=False, keepdb=False, reverse=False, debug_mode=False, debug_sql=False, parallel=0, tags=None, exclude_tags=None, **kwargs)[source]¶ Bases:
django.test.runner.DiscoverRunner
A Django test runner that do not run checks.
marsha.urls module¶
Marsha URLs configuration.
marsha.wsgi module¶
WSGI script for the marsha project.
Module contents¶
Marsha project.