I need your opinion

hi to all
I asked myself to play a little with users and groups of Django for educational purposes
the essence of the idea is as follows:
the user is registered at the same time choosing the type of registration (user type) for example the group “G1” and the group “G2”
after registration, each user gets access to a personal account, which differs (different data) depending on who he is “G1” or “G2”; BUT, in the personal account “G1” there is a button to send a message and then when a user creates a message (from G1), it should go to all users from the “G2” group, and those in their personal account either delete the message or reply to it to the sender from G1 - the answer is as if private.
Now about the models, by analogy with the blog, I think so:

  • Group model (analogy with categories) is the user type “G1” or “G2”
  • Profile1 model (analogy with posts) in which OneToOne with a user model and Foreignkey with a group is for users from “G1”
  • Profile2 model (analogy with posts) in which OneToOne with a user model and Foreignkey with a group is for users from “G2”
  • Messages model (analogy with comments) in which Foreignkey with Profile1

please tell me is this the right approach or not?

I don’t think there’s so much a “right” or “wrong” answer here, just different ways of looking at solutions.

One question that comes to my mind: Is it possible for someone to be a member of both G1 and G2? If not, then I’m not sure that the Group model is the right analogy here, because Group is associated with User as a many-to-many.
If the choice of “G1” or “G2” are truly exclusive, I’d be choosing to model it one of two ways - and that depending upon how similar or different the profile information is between G1 and G2.

But in this case, as an “educational experiment”, I’d be inclined to set this up where the User account is associated with a base User Profile model. In that profile model, I would have all the profile data that is in common between G1 and G2, along with a Generic Foreign Key to an entry to either the corresponding G1 or G2 specific detail data.

One situation that you want to consider carefully is the handling of the case where someone is switched from G1 to G2 after their profile data has been entered. Whatever structure you decide upon, you’ll want to ensure that it’s possible to make sure that the tables are cleaned up - that the “abandoned” profile data gets deleted.

Side Note: In the more general case, I apply what I refer to as the 90-10 rule. When I have two clear choices as to how data should be modeled, I look at how my application is being used. I try to judge the percentage of queries being made that would be optimal one way vs the other. If I’ve got one way that’s going to be used 90% of the time, I’m going to optimize my model for that case, almost regardless of any other consideration.

For example, consider something like a “registration system”, where large numbers of people need to put in information to be reported on or displayed by a small number of people. In that situation, I’m going to optimize my table structures in favor of the people entering their information. When you look at the amount of time that the system is being used, the vast majority of the time is spent with people entering data. It might take longer for the people in the back office to run their reports, but that’s ok - relative to the total time spent of the system being used, they are the “uncommon case”.

Ken

Hello Ken
Thank you for your explanations.
I started to realize my idea. obviously I started creating the model. here is a preventive version:

class SiteUser(AbstractUser):
is_owner = models.BooleanField((‘AE?’), default=False)
username = models.CharField(
(‘username’), max_length=50, blank=True)
email = models.EmailField(_(‘Email address’), unique=True, blank=True)

+++ all fields that match both types of users

class OwnerData(models.Model):
username = models.OneToOneField(SiteUser, on_delete=models.CASCADE, primary_key=True, limit_choices_to={‘is_owner’: True})
company_name = models.CharField(_(‘Company name’), max_length=50, blank=True)

+++ all fields that are only for the second type of user

class Messages(models.Model):
message_sender = models.ForeignKey(SiteUser, …)

@receiver(post_save, sender=SiteUser)
def user_created(sender, instance, created, kwargs):
print(f’
in user_created ‘)
if created and instance.is_owner:
print(f’
owner **’)
OwnerData.objects.create(company_name=instance)

+++ some more field settings in the OwnerData model

Can you tell me your opinion about the structure described above?
Also, can you suggest me some ideas on how to make the message model more accurate, but considering that the message can only be created by how many SiteUser users and this message goes to all users who SiteUser.is_owner = True?