Легкая часть во-первых, с 2) вы на месте. Это был бы самый простой и эффективный способ сделать это. Вместо репликации функций в обоих приложениях имеет смысл иметь одно приложение, которое обрабатывает вещи, общие для обоих типов пользователей.
Вернуться к 1)
С обоими профилями, выходящими из UserProfile, вы столкнетесь с проблемой (если бы вы использовали get_profile () для объекта User - смотрите http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users), что вы получите только объект UserProfile, а не зная, к какой группе пользователь фактически принадлежит, основываясь на полученном объекте, потому что они оба расширяют UserProfile, но UserProfile не сможет (я считаю) абстрагироваться, потому что вы хотите, чтобы каждый пользователь имел указатель на объект UserProfile, который может фактически является объектом UserGroup1 или UserGroup2.
Я бы предложил вам создать две отдельные модели, которые не выходят из одной и той же модели (по необходимости): Group1 и Group2. Вы будете хранить информацию, общую для обоих профилей, в профиле пользователя объекта User. Тогда в UserProfile у вас будет ForeignKey для объекта Group1 и Group2:
group1 = models.ForeignKey(Group1, blank=True, null=True)
Вы должны будете выполнить логику, проверяя себя, чтобы гарантировать, что только один когда-либо действителен (вы могли бы просто сделать это в переопределенном методе save () или чем-то еще), но затем собрать все данные пользователя сразу, а также знать, в какую группу они входят, вы могли бы сделать следующее:
User.objects.filter(username='blahblah').select_related('profile', 'profile__group1', 'profile__group2')
Только один запрос к базе данных даст вам всю необходимую вам информацию о пользователе, и вы также будете знать, в какую группу они входят (та, которая не «Нет»).
Надеюсь, это поможет.
P.S. В этом я предполагаю, что группы имеют не только уникальные данные друг для друга, но и уникальную функциональность.