i am developing a small app for sharing .
to reduce database hit i need a relationship between 2 models (Followers) and (Share)
these are my models
class Follow(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, models.DO_NOTHING, blank=True, null=True , related_name="user_follower")
class Shared(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, models.DO_NOTHING, blank=True, null=True , related_name="user_shared")
class Profile(models.Model):
id = models.AutoField(primary_key=True)
follow = models.ManyToManyField(Follow)
user = models.OneToOneField(User, models.DO_NOTHING, blank=True,null=True , related_name="profile")
class Notes(models.Model):
id = models.AutoField(primary_key=True)
shared = models.ManyToManyField(Shared)
now i wanna do something like this in my django view
def return_users_note_shared_with(request):
followers = request.user.profile.follow.all()
return render(request , 'note.html',{ 'followers':followers})
in note.html how can i check if this note has been share with other users .
i know there is some relationship required in models but i can not
figure this out
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
With these models:
class User(AbstractUser):
pass
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="profile")
bio = models.CharField(max_length=250)
img = models.ImageField(upload_to='img_profiles/')
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="post")
text = models.CharField(max_length=260)
data = models.DateTimeField(auto_now_add=True)
class Following(models.Model):
follow = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follow")
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follower")
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_that_like")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="post_like")
I would need to take data from Post, User and Profile for each Post that has Post.user=Following.follow where Following.follower=request.user.id. Added to that I nedd a Sum of Like.post for each Post catched.
The first part is ok with :
qs=Following.objects.values('follow__post__id','follow__post__text',
'follow__post__data','follow__username','follow__first_name','follow__last_name',
'follow__profile__img').filter(follower_id=request.user.id).order_by('-follow__post__data')
I would like to understand if it is possible to obtain the second part with the same query or if I need a second query / subquery
I would like to understand if it is possible to obtain the second part
with the same query
It is possible with annotation.
You can import Count from django.db.models import Count
and add .annotate(like_count=Count('follow__post__post_like')) to your query
I've got the following models. I need to obtain a queryset of orders where the user's userprofile.setupstatus == 1. Is this possible or should I just add a foreign key field on the Order model to the UserProfile?
class Order(models.Model):
user = models.ForeignKey(UserCheckout, null=True, on_delete=models.CASCADE)
class UserCheckout(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
setupstatus = models.IntegerField(default=0)
It is surely possible with Django ORM
Your query should look somewhat like this
Order.objects.filter(user__user__userprofile__setupstatus=1)
I am creating a small application to help our Training Department manage their cirriculum using Django. When we talk about students we have two type; Employee and Customer.
Since all of the employees will be in auth_user I would rather not have to populate another table with that data. The behavior that I want is when a Class is displayed in the Django Admin I would like one control to be filled with data from two tables for the student list. Is this even possible in Django. My suspicion is that it is not. This is what I am messing around with:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
cell_phone = models.CharField(max_length=14)
class Meta:
abstract = True
class EmployeeStudent(models.Model, Student):
user = models.OneToOneField(User)
extension = models.CharField(max_length=4, null=True, blank=True, default=None)
class CustomerStudent(models.Model, Student):
first_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=25)
email = models.CharField(max_length=25)
However, just thinking about it does it make more sense to do:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
user = models.ForeignKey(User, null=True, blank=True, default=None)
first_name = models.CharField(max_length=25, null=True, blank=True, default=None)
last_name = models.CharField(max_length=25, null=True, blank=True, default=None)
email = models.CharField(max_length=25, null=True, blank=True, default=None)
extension = models.CharField(max_length=4, null=True, blank=True, default=None)
I cringe at the thought of a blank record.
Any recommendations? Does it make sense to add everything to auth_user and leave the staff flag to false then just use a one to one field to map an auth_user to a Student? I do not really want to do that if I don't have to because I am not going to give anyone else access to the auth_user table so all additions to this table would need to be done by me.
You could try to use model inheritance (i.e User model inheritance : https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-user) for your Student model, or mixing Student(models.Model) with User in your EmployeeStudent and CustomerStudent models :
class Student(models.Model):
cell_phone = models.CharField(max_length=14)
class Meta:
abstract = True
class EmployeeStudent(User, Student):
user = models.OneToOneField(User)
extension = models.CharField(max_length=4, null=True, blank=True, default=None)
class CustomerStudent(User, Student):
first_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=25)
email = models.CharField(max_length=25)
or :
class Student(User):
cell_phone = models.CharField(max_length=14)
class Meta:
abstract = True
class EmployeeStudent(models.Model):
user = models.OneToOneField(Student)
extension = models.CharField(max_length=4, null=True, blank=True, default=None)
class CustomerStudent(models.Model):
first_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=25)
email = models.CharField(max_length=25)
If I understand correctly, you'd then want to display Customers as well as Employees in the same changelist in admin ? Using Student(User) with Employee / Customer as inlines might solve your problem.
Hope this helps,
Regards
This is a fairly common use-case (i.e. different types of userprofiles) in Django. In your case, I think the approach below would suit your scenario:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
STUDENT_TYPES = (
('E', 'EmployeeStudent'),
('C', 'CustomerStudent'),
)
user = models.OneToOneField(User, null=True, blank=True, default=None)
user_type = models.CharField(max_length=1, choices=STUDENT_TYPES)
class EmployeeDetails(models.Model):
student = models.OneToOneField(Student)
extension = models.CharField(max_length=4, null=True, blank=True, default=None)
class StudentDetails(models.Model):
student = models.OneToOneField(Student)
# BTW: all the fields below are redundant since they are already in User
first_name = models.CharField(max_length=25, null=True, blank=True, default=None)
last_name = models.CharField(max_length=25, null=True, blank=True, default=None)
email = models.CharField(max_length=25, null=True, blank=True, default=None)
This way, you can check the student.user_type and infer if you need to get EmployeeDetails or StudentDetails
NOTE:: Even though this is a recommended approach, it is not quite easy to enter data using the default admin interface in this manner. You might want to see how profile inlines are done to show the user profile fields in the admin as well.
some body please explain me the following i have two classes Userprofile and Staff.staff inherits userprofile
My Question is that if any entry has to be made to a staff table .1.It would be mandatory to fill out the details of user profile right?
Please explain this inheritence.Thanks
class Profile(models.Model):
user = models.ForeignKey(User, unique=True)
created_date = models.DateTimeField(auto_now_add=True)
emp_first_name = models.CharField(max_length=255)
emp_last_name = models.CharField(max_length=255)
gender = models.CharField(max_length=2, choices = GENDER_CHOICES, null=False)
date_of_birth = models.DateField(blank=True,null=True)
address1 = models.CharField(max_length=255)
city = models.CharField(max_length=48)
state = models.CharField(max_length=48)
country = models.CharField(max_length=48)
email_id = models.EmailField(blank=True)
class Staff(UserProfile):
role = models.ManyToManyField(Role)
designation = models.CharField(max_length=48, blank=True, null=True)
education = models.CharField(max_length=255, blank=True, null=True)
If you take a look at https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance you'll see that automatic One-to-One mappings are created. Therefore, an entry for UserProfile is saved, and an entry for Staff is saved with a OneToOne field that points to the UserProfile entry.
However, if you want Staff to just inherit all the fields, I'd recommend setting abstract = True in your UserProfile. This means that Staff inherits all those fields, but you can never create a UserProfile by itself (as described at
https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes )
class Meta:
abstract = True