Why is your code added to “common”?
Common is a Django project that is fully contained within the edx-platform repository. It contains a set of Django apps that are shared between Course Management Studio (cms) and the Learning Management System (lms). Note that the edx-platform repository contains four distinct Django projects: cms, common, lms, and openedx. Strictly technically speaking, you could place your custom Django app in any of these four. So, why did we choose “common”?
At the risk of over-complicating matters, there is a fifth option which I actually prefer above these four obvious possibilities, which is to bundle your code as a standalone git repository that is added to requirements.txt and installed by pip. We ignore this possibility in this tutorial solely because it requires a deep understanding of pip as well as some subtleties of how the developers at edX go about managing the sizable number of dependencies in the Open edX project.
We chose “common” because it is in the application search paths of both lms and cms. Though unimportant for purposes of this tutorial, this could turn out to be helpful for other future custom programming tasks.
We avoided “openedx”, which for avoidance of any doubt, is also in the search paths of lms and cms, but which contains a more complicated file system structure that potentially adds a bit more complexity to how we might have to address and import our custom code.
The actual source code in Github includes a namespace. This is important.
In my forked repository of edx-platform the actual address to the custom Django app is
common.djangoapps.lawrencemcdaniel.custom_login.apps.CustomLoginConfig, which includes the name space “lawrencemcdaniel”. Consolidating all of your custom Django apps inside your own name space is an important strategy for avoiding future naming collisions in future releases of Open edX software.
Why use Django Dispatch rather than creating a custom user model, which is exactly what Django suggests in their documentation?
Yeah, great question! why not just do what Django tells you to do in their official documentation?
Django provides a way customize authentications, by creating a custom user model. So, why not do this? The short answer is that edX has already done this, by implementing the “student” Django app which is also their alternative Django user model. Thus, in Open edX software all users (learners, instructors, staff, admins) are “student” regardless of whether or not that’s true in real life.
The first problem with subclassing edX’s subclass of the Django user model is that your new code would touch literally every part of the Open edX code base, not only in lms but also cms. Thus you would need to exhaustively test every line of edx-platform just to determine if your custom subclass of “student” breaks anything in the current code base (which it very likely would). But then you would also have to re-test just as exhaustively for all future releases of the software, and you would run the same high risk of your custom user model breaking future code as well.
So, the longer answer is that this approach is bad risk-reward.
My learners authenticate via oAuth and third_party_auth provides a way to customize authentications via pipeline.py
If you’re already familiar with how pipeline.py works, why not put your customization there? The problem with pipeline.py is that it is only called in the cases where authentication occurred via some form of third party authentication. Your code will be skipped entirely if users authenticate with a username and password.
Implementing your customized login via Django Dispatch Signals ensures that it is applied to all users in all authentication scenarios.