I have two models user and posts. Each post is associated to a user and user can follow each other and the user model contains a field called is_private_profile depending on which user's posts are visible to eveyone or only to those who follow the user.
I want to fetch all the posts whose authors have public profile and the posts for users with private profile only if the user who wants the post follows him
class Posts(models.Model):
author = models.ForeignKey(User, verbose_name=_(
"Author"), on_delete=models.CASCADE, related_name="posts")
caption = models.TextField(_("Caption"))
created_at = models.DateTimeField(
_("Created At"), auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(
_("Updated At"), auto_now=True, auto_now_add=False)
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_("Email"), max_length=254, unique=True)
follows = models.ManyToManyField("self", verbose_name=_(
"Followers"), symmetrical=False, related_name='followed_by')
is_private_profile = models.BooleanField(
_("Is Private profile"), default=False)
All the posts whose authors have public profile:
Post.objects.filter(author__is_private_profile=False)
All the posts whose authors have private profile:
Post.objects.filter(author__is_private_profile=True)
EDIT:
All posts depending on whether the currently logged in user follows the author or not
Post.objects.filter(author__follows=request.user).distinct()
Related
I have multiple types of user in my django app: Employee and Patient. They have fields that are specific to each of them. They are implemented using the AbstractBaseUser model as below:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
username = models.CharField(max_length=40, unique=True)
USERNAME_FIELD = 'identifier'
first_name = models.CharField(
max_length=50, null=False, blank=False)
last_name = models.CharField(
max_length=50, null=False, blank=False)
date_of_birth = models.DateField(null=False, blank=False)
USER_TYPE_CHOICES = (
(1, 'Patient'),
(2, 'Employee'),
)
user_type = models.PositiveSmallIntegerField(
choices=USER_TYPE_CHOICES, default=1, blank=False, null=False)
class Role(models.Model):
RoleName = models.CharField(max_length=50, null=False, blank=False)
class Employee(models.Model):
user = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True)
employment_start_date = models.DateField(null=False, blank=True)
employment_end_date = models.DateField(null=False, blank=True)
role = models.ForeignKey(
Role, on_delete=models.CASCADE, related_name='assigned_employees')
class Patient(models.Model):
user = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True)
I have a few questions with how to go forward with this:
How does just the choice in the User class limit the fields that a user has access to? If I had a HTML page would I create an Employee then a User would be created, or the other way round?
When I'm using Django Rest Framework, how can I implement a sign up and log in with the two different types?
I'm struggling to understand how this would work conceptually. Is like Employee and Patient a subclass of User? Or are they separate models? Any help or advice would be greatly appreciated
In your code you don't have two types of User. You have only one type - class User(AbstractBaseUser). Employee and Patient are normal models that are only related to User.
If you wanted to create two types of User with actual inheritence, then you should do following:
class AbstractUser(AbstractBaseUser):
class Meta:
abstract = True
# main user fields here
class Employee(AbstractUser):
# employee fields here
class Patient(AbstractUser):
# patient fields here
If you don't want to do this, your current approach is good. You can simply authenticate User in standard way. During creation you can make seperate forms for registering employee User, that creates automatically related Employee class. Similar for Patient. They will share only fields of User class with either approach.
To authenticate in different ways you can use custom authentication with authenticate() function. Read specifics in Django Docs
For instance I have these models:
class Company(models.Model):
name = models.CharField(max_length=100)
class User(AbstractBaseUser):
email = models.EmailField(max_length=250, unique=True)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
is_admin = models.BooleanField(default=False)
Now I can easily get all the profiles for a company using the following query:
Company.objects.first().profile_set.all()
But is there a way I can get the related users from company instead of profile, keeping in mind that a user object is one to one related with profile object?
Note: These models are just example models, and keeping in view the application logic, we can't combine user and profile model.
company = Company.objects.get(id=X)
User.objects.filter(profile__company=company)
or create a manager on Users:
def from_company(self, company: Company):
return self.filter(profile__company=company)
https://docs.djangoproject.com/en/4.0/topics/db/managers/
I have the two models, One is the User model and the other is a Contact model.
The Contact model is as follows:
class Contact(models.Model):
pass
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, on_delete=models.CASCADE, verbose_name=_('User'), related_name="user")
contact = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, on_delete=models.CASCADE, verbose_name=_('Contact'), related_name="contact")
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
is_contact = models.BooleanField(default=False)
Basically, what is does is create a contact for a user. Kind of a friend request and accept simple model. So the loggedIn user(request.user) could be either the contact.user or contact.contact.
And the settings.AUTH_USER_MODEL is a CustomUser model:
class CustomUser(AbstractUser):
pass
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=20, default="", blank=True)
last_name = models.CharField(max_length=20, default="", blank=True)
How can I create a relationship, where I can get a users contact by doing something like this:
// get user contacts user=CustomUser.objects.get(pk=1)
user.contacts.objects.all()
Typically you query reverse relations using the related_name keyword, which is contact_set by default:
user.contact_set.all()
If you want to change the name of this reverse relationship, you need to do so in the Contact model using related_name:
class Contact(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="contacts", ...)
user.contacts.all()
I have the following model:
class Task(models.Model):
site=models.OneToOneField(Site,on_delete=models.CASCADE,default=1)
executor=models.ManyToManyField(People)
It is related to the following model:
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,
unique=True)
phone_number = models.CharField(max_length=200, blank=True,
null=True)
#department = models.CharField(max_length=200, blank=True, null=True)
title = models.CharField(max_length=200, choices= titles, blank=True,
null=True)
What I want is that in DjangoAdmin in the field executor only people__title='titleone' was displayed. So that the executor search field would not be overload with other people who cannot ever be related to the Tsk since I have them in the same database.
You can override get_queryset() in admin.py file and can restrict queryset to include only that query which contain people__title='titleone'.
I have a custom user model that I am building in Django. I'm pretty clear on how its going to work.
I though have an interesting permisions scheme.
I am trying to confrim if my thought process is correct.
Each user can be part of many venues. Of each venue a user is a part of they may have a different permission.
I have my user table and then I have a permissions table
the permissions table is of the following:
pk
venueID
UserID
isclient
isvenueviewer
isvenueeventplanner
isvenueadmin
issuitsviewer
issuitssuperuser
the venue id can be null meaning that no all users will have venues attached to them.
my thought is that a user first gets authenticated by the user table then that user object is checked by the permissions table for what permissions that user has. Of those permissions the one needed for the current view to be authorized is filtered through. And see if valid.
am I spot on?
Thank you hugs and kisses!
so after research all i need to do is set up a many to many relation on the STuser table and we are set. Shown below.
class Permissions(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE, blank=True, null=True)
isclient = models.BooleanField(default=False)
isvenueviewer = models.BooleanField(default=False)
isvenueeventplanner = models.BooleanField(default=False)
isvenueadministrator = models.BooleanField(default=False)
issuitsviewer = models.BooleanField(default=False)
issuitsadministrator = models.BooleanField(default=False)
issuitssuperuser = models.BooleanField(default=False)
class STUser(AbstractBaseUser):
email = models.EmailField(unique=True)
name = models.CharField(max_length=255)
companyname = models.CharField(max_length=200, blank=True, null=True)
userphoto = models.CharField(max_length=200, blank=True, null=True)
signupvaildatestring = models.CharField(max_length=200, blank=True, null=True)
is_active = models.BooleanField(default=False)
phone = models.CharField(max_length=10, null=True, blank=True)
jobtitle = models.CharField(max_length=100, null=True, blank=True)
permissions = models.ManyToManyField(Permissions)
# password field function is provided by AbstractBaseUser
#objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
EMAIL_FIELD = 'email'