Best practies? Две независимые модели для пользователя и админа, Django 1.11.x?
Я не раз видел попытки такого разделения пользователей по классам в проектах на Django. Не знаю, почему все сразу выбирают такое решение, которое в перспективе не приносит ничего, кроме боли.
Проще всего пойти стандартным путем: унаследовать пользователя от django.contrib.auth.models.AbstractUser, а различие между пользователями определять либо по группе/разрешениям, либо добавить поле в свою модель типа is_moderator. Это будет во много раз (на порядок точно) проще реализовать и поддерживать, будет совместимость со всем стандартным кодом Django и сторонними библиотеками, любому просто войти в проект и внести изменения.
Разделение на две разных модели никаких абсолютно преимуществ не дает, кроме тонны мусорного кода и головняков с поддержкой данной гидры.
TLDR:
1) Из вашего вопроса остается неясным, почему требуется разделение по разным классам. Это самый безумный вариант для разграничения полномочий, и в Django разделение полномочий пользователей уже предусмотрено по умолчанию
2) Поддерживал пару проектов с разными классами для разных классов пользователей. Поверьте, это просто ужас-ужас в поддержке, а самое главное, что он ничем не оправдан.
Делить пользователей на две таблицы не стоит, хотя бы потому, что множество библиотек сразу же не сможет с такой системой работать, или придётся писать костыли.
Я думаю, что проще всего использовать стандартную модель User + свою модель Profile, подключённую через OneToOneField. В ней можно собирать все необходимые свойства. Что мешает модератору сайта одновременно быть покупателем футболочек? Собственно ничего.
А теперь что касается проверок на is_staff. Посмотрите django-braces. Вам достаточно использовать class based views и подключать нужные mixins, - и вы забудете об этих проверках: большая их часть будет выполняться в mixins, а не в бизнес-логике предметной области. Вы можете и свои классы для этого дела написать.