Making a function in a app that changes fields in another app - django

Hi Djangonauts,
I am new to Django so please forgive any errors in logic or code
I have a accounts app that has a Profile model with a field is_verified Now I have another app called verification. That has a model Verification and a field called verify I want to create a logic such that when you verify the user on the verification app. The is_verified on profile app is also marked as True
models.py for Profile
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=100)
country = models.CharField(max_length=100)
is_verified = models.BooleanField(default=False)
models.py for Verification
class Verification(models.Model):
user = models.ForeignKey(User, related_name='verified')
applied_on = models.DateTimeField(auto_now_add=True)
verify = models.BooleanField(default=False)
deny = models.BooleanField(default=False)
verified_on = models.DateTimeField()
denied_on = models.DateTimeField()
def verify_a_user(self, user):
self.verify = True
user.profile.is_verified = True
return user.profile.is_verified.save()
Is this correct? Is there a better way to execute this code

Take a look at https://docs.djangoproject.com/en/2.0/topics/signals/
Either send a pre_save or post_save signal from your Verification model.
https://docs.djangoproject.com/en/2.0/ref/signals/#django.db.models.signals.pre_save
https://docs.djangoproject.com/en/2.0/ref/signals/#django.db.models.signals.post_save
Then register the listener function in your Profile app.
For details and example
https://docs.djangoproject.com/en/2.0/topics/signals/#connecting-to-signals-sent-by-specific-senders

Related

Created m2m fields values are assigned to all existing users

I try to create a user profile with a many to many relation.
Those are my models:
class Job(models.Model):
CARRYING = 'carrying'
CARRYING_FOR_MOVE_TOOLS = 'carrying_for_move_tools'
CHOICES = [
(CARRYING, 'yyyyyyyyy'),
(CARRYING_FOR_MOVE_TOOLS, 'xxxxxxxxxx'),
]
job = models.CharField(max_length=1000,
choices=CHOICES,
primary_key=True,
default='',
unique=True)
display_sort_key = models.FloatField(default=0.)
def __str__(self):
return self.get_job_display()
def get_slug_prefix(self):
return self.SLUG_PREFIX[self.job]
class Userprofile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
email = models.EmailField(max_length=70)
jobs = models.ManyToManyField(Job)
def __str__(self):
return self.email
When i create Jobs in the admnin panel or send the jobs via the client interface (Angular), all created jobs are assigned to all existing userprofiles.
How can i create a Jobs in Django admin panel without those jobs are assign to the all existing userprofiles?
or
How can i assign in Django Admin panel the Jobs-data send from Angular only to the userprofile of the logged user ?

Filter and get all the customers who had brought the authors other contents to send the notification when new content is added

I want to Filter and get all the customers who had brought the authors other contents to send the notification when new content is added This works on queryset I know but I'm Confused on how to do that. If anyone please share.
Here are my models
content:
class Content(models.Model):
title = models.CharField(max_length=1000)
Author = models.ForeignKey('User',on_delete=models.CASCADE)
slug = AutoSlugField(populate_from='title', unique=True, null=False)
cover = models.ImageField(upload_to='course', default='nocover.jpg')
catogary = models.ForeignKey(Category, on_delete=models.RESTRICT)
description = models.TextField(max_length=2000, null=True, blank=True)
requirements = models.TextField()
price = models.FloatField()
language = models.ForeignKey(Language, on_delete=models.RESTRICT)
Puchased content
class PurchasedContent(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Course, blank=True, related_name='course')
I want all the list of Customers email who had brought a particular Authors course
the Author will be authenticated while adding. We'll get the Author as request.user
Here is sample ListCreateAPIView in django rest Framework
class createlistcontentview(generics.ListCreateAPIView):
permission_classes = [TokenHasReadWriteScope]
queryset = Content.objects.all()
serializer_class = ContentSerializer
def perform_create(self, serializer):
#Here I want to get a list of mails to create a Function that sends mall
serializer.save(author=self.request.user)
So what you can do is use a signal to send the email to the users whenever a content is created like this:
from django.dispatch import receiver
# models.py
#receiver(models.signals.post_save, sender=Content)
def send_email(sender, instance:Content, created, **kwargs):
if created:
# import and use your email helper here
# since the related name you chose for the purchased_content course is a little confusing I changed it to `purchased_content`
purchases = instance.course.purchased_content.all()
send_email(users=[user.email for user in purchases])
return

Why does Django not find a field added to the AbstractBaseUser

I've inherited from the AbstractBaseUser as follows:
class User(AbstractBaseUser):
"""
Main User model, inherits from AbstractBaseUser
"""
# Meta
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.CharField(max_length=40, unique=True) # equals to email
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True)
So each User is linked to one and only one Customer.
Now within a view I want to access the instance of the current logged in user within the request object and get the employee_of value to get a queryset that contains all users of that customer.
def render_employees(request):
"""
Renders the employees page of the dashboard
:param request:
:return:
"""
# Return the value for the current site for css specific classes
dashboard_site = 'employees'
# Query the employees
qs_employees = User.objects.filter(employee_of=request.user.employee_of) # doesn't find field
...
However the filter doesn't work because request.user.employ_of doesn't seem to return anything. My IDE even suggests e.g. username, date_joined etc. but not employee_of.
Why's that?
class Customer(models.Model):
"""
A table that stores static data about a customer, usually a legal company
"""
legal_name = models.CharField(max_length=50)
street = models.CharField(max_length=30)
street_number = models.CharField(max_length=3)
def __str__(self):
return self.legal_name
Update:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from applications.customer.models import Customer
from django.conf import settings
BaseUser = settings.AUTH_USER_MODEL
class User(AbstractBaseUser):
"""
Main User model, inherits from AbstractBaseUser
"""
# Relations
user = models.OneToOneField(BaseUser, related_name='user_profile', on_delete=models.CASCADE, null=True) # link to default user model
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True, blank=True)
I linked the user to the default user model via Django admin. However in the view im still not able to access employee_of within request.user
It seems that request.user is a different model. It's User model from django.contrib.auth. https://docs.djangoproject.com/en/4.0/ref/contrib/auth/#django.contrib.auth.models.User.
What you can do about it?
In our app we have UserProfile model that have OnetoOne relation to django User.
You can then store employee_of value there.
class UserProfile(AbstractBaseUser):
user = models.OnetoOneField("auth.User", related_name="user_profile", on_delete=models.CASCADE)
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True)
and then access request.user employees using something like
request.user.user_profile.employee_of

Django - Creating a row in onther table before creating user

I have user, userprofile and company tables.
I want to create a record in company table and then assign the id of the newly created company in the userprofile foreign key before creating the user. I think it can be done using pre_save signal but I am unable to figure how. Please help.
Here's some details as AMG asked:
I have django's builtin user model
a userprofile model
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='profile_pics/default.jpeg', upload_to='profile_pics')
bio = models.TextField(blank=True, verbose_name='Biography')
company_name = models.ForeignKey(Company, on_delete=models.CASCADE)
a company model
class Company(models.Model):
name = models.TextField(blank=True, verbose_name="Company Name")
nof = models.IntegerField(verbose_name="No. of Employees")
All three are related user and userprofile has one to one relationship, and userprofile and company has many to one relationship.
I want Company record to be created first and than that new record's reference needs to be put into userprofile.
I think I have made it clear now.
Exactly, you can use pre_save for this. You can just put this in models.py below your defined models.
from django.db.models.signals import pre_save
#receiver(pre_save, sender=Profile) # register your model to the signal pre_save
def my_callback(sender, instance, *args, **kwargs):
if not instance.company_name: # check if instance has a value for company_name
company = Company.objects.create(
name='Test',
nof=1
)
instance.company_name = company
OR
Create a default value through a function.
class Company(models.Model):
name = models.TextField(blank=True, null=True, verbose_name="Company Name") # set blank=true and null=true so you can save an empty instance
nof = models.IntegerField(blank=True, null=True, verbose_name="No. of Employees")
def profile_company_default():
return Company.objects.create()
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='profile_pics/default.jpeg', upload_to='profile_pics')
bio = models.TextField(blank=True, verbose_name='Biography')
company_name = models.ForeignKey(Company, on_delete=models.CASCADE, default=profile_company_default) # add function as default value
EDIT
To edit company after save.
profile = Profile.objects.create(key="value")
profile.company.name = "Company Name"
profile.company.nof = 5
profile.save()

Django ModelForm: Huge ForeignKey queryset leads to crash when loading form

Basically, I have two models: User and Event. An event is always associated with one user.
class User(models.Model):
user_id = models.AutoField(primary_key=True)
username = models.CharField(max_length=255, unique=True)
hashed_password = models.CharField(max_length=255)
class Event(models.Model):
event_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=255)
description = models.TextField(max_length=255, blank=True, default='')
user = models.ForeignKey(User)
And then I have the following form for Event.
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['title', 'description', 'user']
I can succesfully show this form in my template to create an event. I can also associate a user to a form successfully with Select field when the users number are still few.
Now the problem is, when I have 1M users in database, my browser crashes when loading the template. Any idea how to solve this one? I was thinking about using AJAX and then search user that matches the username, but I'd like to hear other better approaches. Thanks!