Django Form save - circular dependency - django

I have 2 models Account and User. An Account can have multiple users.
When the first User(Owner) is created at the same time the Account will be created.
Because User have a ForeignKey to Account, I need first to create the Account, and after the User.
But Account had a field created_by which is request.user. So is a circular problem.
I think I need to create first the Account and created_by to be a superuser(first) and than create the User, and update the Account with the new user.
class Account(MetaData):
name = models.CharField(max_length=255)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True,
related_name='%(app_label)s_%(class)s_created_by', on_delete=models.CASCADE)
class User(AbstractBaseUser):
account = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='owner')
How can I do that ?
I need this only first time, for the first user, because after that for the other users the Account will exist.
When I'm saying first user, I'm not referring to staff users (as superusers), but normal users for which an account is mandatory thru a register form.
blank=True is just for staff members.

Your User model's account field allows nulls, so nothing prevents you from first creating the user without an account, then creating the account with this user, and finally updating the user with the account:
with transaction.atomic():
user = User.objects.create(account=None, ...)
account = Account.objects.create("test", created_by=user)
user.account = account
user.save(update_fields=["account"])

Since it's only a problem for the first user, you might want to override the method create_superuser of the manager to add the account. Also, since you've defined the ForeignKeys with null=True, it should not be a problem to first create a superuser (using super().create_superuser()) and then create the account and attach it to the superuser.
When deploying your site the first time, you'll have to manually run the ./manage.py createsuperuser command.

Related

How to get a django instance to have one to many users relation

I have a company table as follows:
class Company(models.Model):
users = models.ManyToManyField(settings.AUTH_USER_MODEL, default=None)
My plan is that a given company instance can have more than one user account tied to it.
But from above, when a company is created, the users field is ending up with all the users in the users table.
That is not I want. I want that users are manually added rather than just populating the field with all users in the database:
How can I set this up so that a given company instance can only have the users added to it rather than all database users?

Unsure of approach for Django custom user groups and permissions

I am creating my first Django (ver 3.1) website which is simply a blog with a home page and store page. I want to create custom user groups that define specific roles (with unique permissions) for my blog.
These groups are:
Reader - anonymous viewers and new accounts; has read permission for all content only
Author - login required; has read and create permissions; edit and delete permissions for own content only
Moderator - login required; has all CRUD permissions for all content
Admin - login required, has all permissions (superuser)
All new users by default are in the Reader group. Author would either be assigned manually or eventually by an online form application to determine eligibility. Moderator and Admin would of course be manually assigned.
I am approaching this with possible future development, such as allowing user groups to be easily extended to other website pages. For example, a 5% discount for Author users applied to all store items, etc.
Which approach to creating user groups would be best for my situation? I have seen it done within the Django Admin Panel and by creating custom User Models via extending the AbstractBaseUser and UserBaseManager classes.
I think extending the AbstractUser model is a good approach. How about something like this?
class CustomUser(AbstractUser):
"Define the extra fields related to User here"""
first_name = models.CharField(_('First Name of User'), blank=True, max_length=20)
last_name = models.CharField(_('Last Name of User'), blank=True, max_length=20)
#  - - - Some more User fields according to your need s
class Meta:
permissions = (("can_read_content", "To provide read facility on all content"),
#---------------------
)

Permissions from 2 django projects are merged. How to separate them?

Good day to all)
I created a custom user model with custom permissions. I have several projects and their permissions merged into one table('auth_permission'). Is it possible to somehow customize the table itself for these permissions to separate projects?(like db_table = '"schema"."table"' to the models.).Google did not give answers.
class TestUser(AbstractUser):
phone = PhoneNumberField(null=False, blank=False, unique=True)
email = CharField(unique=True, max_length=35, null=False, blank=False)
class Meta:
db_table = '"fyzzys"."users"'
permissions = [
("can_see_payments", "payments"),
("can_see_analytics", "analytics"),
]
UPD: Here is a screenshot that shows the permissions of two completely different projects at the same time from admin panel.
In order to give a user permissions, you will want to add the PermissionsMixin to the User model like so.
class TestUser(AbstractBaseUser, PermissionsMixin):
If you are using the AbstractUser you are actually already inheriting the PermissionsMixin.
The permissionmixin is a model within django.contrib.auth.models. It adds to the user model the following fields (columns in the user table); is_superuser, groups, user_permissions. The permissions mixin allows you to add (and remove) 0..*(many) individual or group permissions to a user.
To add permissions to a user you can then use.
from django.contrib.auth.models import Permission
# The permission needs to exist first.
permission = Permission.objects.get(name='Can view poll')
u.user_permissions.add(permission)
The code for for the django.contrib.auth.models.permissionsmixin can be found following the link.

Access User fields using UserProfile object

I want to access User model fields using UserProfile object.
I have a 'role' field in Userprofile,
class UserProfile(models.Model):
user = models.OneToOneField(User)
role = models.CharField(max_length=30)
Each user has a role, 'supervisor' or 'admin' now I want to get the user objects whose role=supervisor. I want to be able to access the username of those users with role supervisor which is in User model customized.
I cant get the query right. Help please.
supervisor_usernames = [up.user.username for up in UserProfile.objects.filter(
role='supervisor')]

django multiple related_name() search filter

I have a profile.
class UserProfile(models.Model):
user = models.ForeignKey(User, related_name="%(class)s", unique=True)
providers = models.ManyToManyField(ServiceProvider, related_name="%(class)s")
class ServiceProvider(models.Model):
name = models.CharField(max_length=200, null=False, default="ims")
How do I get to the user object with just having the profile object.
Can I do: (assuming I have my service provider object)
provider.userprofile.user.get() // or something like that.
I'd like to do that in one sql query. So if I had just the pk of the provider, it would be great to get to the user profile and/or the user that holds that provider.
Since your User is just a foreign key, all you need is provider.userprofile.user
If you don't want that to incur a second SQL query, you can just use the select_related option when selecting your profile, like:
UserProfile.objects.get(pk=<the_id>,select_related=True)
As written, your models don't provide a trivial way to get from the provider to the User, since there is a ManyToMany from the ServiceProvider to the UserProfile. You'll have to get the set of UserProfiles associated with the provider, get the one you want, and then proceed to get the User as above.