django ManyToManyField unique - django

class Building(models.Model):
address = models.CharField(max_length=20, primary_key=True)
employers = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="employers",
blank=True)
Suppose n users of model type User and m buildings of model type Building (m << n). I would like in the Admin page to be able to put users into building in the unique way:
a user can be in maximum one building.
a building can have many employers. It can be empty too.
in the Admin page, in the Employers selection widget, in the UPDATE
mode, exclude users that belong to another building. In the CREATE
mode, show only users without a building.
Stack: Django, MySQL.

So, basically you need inside User model one field with Foreign key relationship with Building and you can query it with related name.
example:
class User(AbstractUser):
"""
Your user model
"""
building = models.ForeignKey(Building, related_name='building_employers', on_delete...)
...
Later you can query employers with building_object.building_employers.all()
For question number 3, please check:
https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.TabularInline

Related

Filter django query set based on whether a foreign key relationship exists

So I have two models.
class Post(models.Model):
id = models.OidField('object id', unique=True)
class ArchivedFlag(models.Model):
post = models.ForeignKey(post,
on_delete=models.CASCADE,
related_name='archived_flag')
user = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='archives')
In views.py I have generated a list of all posts by some criteria, 'plist'.
I want to filter the list based on posts that DO NOT have an ArchivedFlag object relationship. Basically the ArchivedFlag model is a tool hide certain posts.
How can I do this? I'm trying to do something along the lines of
plist = plist.exclude(models.ForeignKey.Post exists)
but I'm unsure of the exact syntax.
You can exclude Post objects for which anArchivedFlag exists with:
Post.objects.exclude(archived_flag__isnull=False)
or easier with a simple filter:
Post.objects.filter(archived_flag=None)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

How do I update the django models on runtime?

I have a normal Django model. I want to give a certain user the ability to add custom fields. I want the model to update during runtime and the database migrations to apply and then the user can do regular CRUD operations.
Example of a simple Model is
class location(models.Model):
AuotLocationID = models.CharField(max_length=200)
LocationID = models.CharField(max_length=200)
Name = models.CharField(max_length=200)
The user should be able to add other model fields such as Postal Code, Population, etc. Also each instance of the model should be linked to each user. For example Bob may want to track certain fields for his location and John may want some other fields.
Thank you for your help

Most convenient way to get related object in Django

I need to render different templates for logged in user depending on its "type":
I have a custom User called Users to store the general fields, and three different user types, called Admins, Publishers and Copywriters, linked to the Users table with One-To-One relation
class Users(AbstractUser):
# fields
class Admins(models.Model):
user = models.OneToOneField(Users, on_delete=models.CASCADE)
# extra fields for admins...
class Publishers(models.Model):
user = models.OneToOneField(Users, on_delete=models.CASCADE)
# extra fields for publishers...
class Copywriters(models.Model):
user = models.OneToOneField(Users, on_delete=models.CASCADE)
# extra fields for copywriters...
Which is the most convenient way tho retrieve the related fields of the logged user? Or in other words, how can i retrieve the admins or publishers or copywriters object related to the logged user?
My original idea was to add a column in the Users table called user_type but it seems to me a redundant field since there's a One-To-One relation

How to implement two authentication layers in django

I have a web application for businesses. Upon login, a user (the manager of the business) can view tables with information about their business.
userID 1->* rows in a MasterTable,
userID 1->* rows in a ForecastTable
I need to change it so an owner of multiple businesses can log into the account for a specific business and edit the same information that the manager can.
I was thinking about changing the database schema to something like this:
userID - businessID 1-* rows in MasterTable, rows in ForecastTable
Should I have 2 login pages, first for the userID, then the businessID. Then all the columns in the database only reference the businessID, so different users can edit the same data.
Or the same login form makes the user enter a businessID, and their username, then depending on which businessID they enter, it logs into that page?
I'm not sure what is the best practice to implement something like this.
Here is what my django model looks like:
from django.db import models
from django.contrib.auth.models import User
class MasterEntry(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField()
cutoff1 = models.IntegerField(default=0)
cutoff2 = models.IntegerField(default=0)
rooms_sold = models.IntegerField(default=0)
is_blackout = models.BooleanField(default=False)
class ForecastEntry(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField()
rate = models.IntegerField(default=0)
A user has hundreds of these 'master entry' and 'forecast entry' rows. I query the database for the rows and create a table in the front end.
You don't need two layers of authentication.
For instance, a user which is not admin only can view business he owns, this is achieved with a simple filter in the view displayed the mentioned list of business.
And you could render each business name as a link that then shows a list of MasterEntrys in it.
This is more a problem with information layout.
Conclusion:
Show a page only with business belonging to the authenticated user.
Superuser can see all business.
You can click a business entry in order to view/edit/delete any of the MasterEntrys it contains.

Django models: database design for user and follower

In Django model I am making a table 'followers', which has:
user's id. (this is followed by)
user's id (this is follower)
that's simple a user can follow other users.
How should I define the model in Django?
I tried this, but does not work:
user = models.ForeignKey('self')
follower_id = models.ForeignKey('self')
How should this be done?
thanks
The 'self' argument won't work unless you have a model called self.
Assuming that your assignment model is called Following, and you're using the built in User model then you can do:
class Following(models.Model):
target = models.ForeignKey('User', related_name='followers')
follower = models.ForeignKey('User', related_name='targets')
This will likely need some further uniqueness and validation logic.
Note the related_name attribute, see https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_name. This means that for a given user object you can do user.targets.all() to get users they follow, and user.followers.all() to get users who follow them.
Note also that Django returns target model instances, not IDs, in the ORM. This means that even though the underlying table may be called follower_id, in the python code following.follower will return an actual User object.
Seeing as Following is actually the through table for the many-to-many relationship between Users. I would create a Profile model which extends the Django User model, and then declare the many-to-many relationship (using ManyToManyField).
from django.contrib.auth.models import User
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
following = models.ManyToManyField(User, related_name='followers')
Use the many to many field.
followers = models.ManyToManyField('self', symmetrical=False)