If/when statement in django models to create another model field - django

I'm trying to create a model field that is a result of another model field. I am unable to articulate this properly, but I will try anyway.
I have employees who include everyone in the office, then I have a role for them too.
All the staff are Engineers, and a few of the Engineers are also Managers. so when creating an Employee, I have to select if they are just an Engineer or a Manager.
if the role is a Manager, then I want to create a model field as
manager = models.Charfield(???????????)
from django.db import models
class Roles(models.Model):
role = models.CharField(max_length=22)
def __str__(self):
return self.role
class Engineers(models.Model):
region = (
('SS', 'South-South'), ('SW', 'South-West'), ('SE', 'South-East'),
('NE', 'North-East'), ('NW', 'North-West'), ('NC', 'North-Central'),
)
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
email = models.EmailField(max_length=50)
username = models.CharField(max_length=20, unique=True)
phone = models.CharField(max_length=11)
position = models.ForeignKey(Roles, on_delete=models.DO_NOTHING, max_length=20)
workarea = models.CharField(max_length=20, choices=region)
manager = models.(if role selected = Manager), then the Employee name should be here
def __str__(self):
return self.firstname + ' ' + self.lastname
I'd appreciate any help or redirection to any resources that can help or any different way of doing this.
the manager field should be a dropdown of the list of existing employees with the Manager status.

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 ?

Create object if not exists in Django ImportExportModelAdmin

I have these two models:
Profile_model.py
class Profile(models.Model):
firstname = models.CharField(max_length=200, blank=False)
lastname = models.CharField(max_length=200, blank=False)
email = models.CharField(max_length=200, unique=True, blank=False)
...
Investment_model.py
class Investment(models.Model):
invested = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
...
and I have this admin:
Investment_admin.py
class InvestmentResource(resources.ModelResource):
...
firstname = fields.Field(attribute='profile',
widget=ForeignKeyWidget(Profile, field='firstname'),
column_name='firstname')
lastname = fields.Field(attribute='profile',
widget=ForeignKeyWidget(Profile, field='lastname'),
column_name='lastname')
email = fields.Field(attribute='email',
widget=ForeignKeyWidget(Profile, field='email'),
column_name='email')
class Meta:
model = Investment
fields = (
'firstname',
'lastname',
'email',
'invested',)
export_order = fields
class InvestmentAdmin(ImportExportModelAdmin, admin.ModelAdmin):
...
resource_class = InvestmentResource
...
I am using django's ImportExportModelAdmin for bulk imports and exports but when I try to import, I get this error:
I get that its producing this error because the profile hasn't been created yet. But what do I have to do to implement an update_or_create inside the ImportExportModelAdmin?
Option 1 is to use before_import() to scan through the dataset and create Profiles in batch if they do not exist already.
Option 2 is to override methods and create the profiles just before the Investment row is imported. This is only necessary for new Investment objects. This assumes that 'email' will uniquely identify a Profile, you will need to adjust this if not.
Note that firstname and lastname can be set on the Profile object before it is created.
class InvestmentResource(resources.ModelResource):
firstname = fields.Field(attribute='profile__firstname',
widget=CharWidget(), column_name='firstname')
lastname = fields.Field(attribute='profile__lastname',
widget=CharWidget(), column_name='lastname')
email = fields.Field(attribute='email',
widget=ForeignKeyWidget(Profile, field='email'),
column_name='email')
def before_import_row(self, row, row_number=None, **kwargs):
self.email = row["email"]
def after_import_instance(self, instance, new, row_number=None, **kwargs):
"""
Create any missing Profile entries prior to importing rows.
"""
if (
new
and not Profile.objects.filter(
name=self.email
).exists()
):
obj, created = Profile.objects.get_or_create(
name=self.email
)
if created:
logger.debug(f"no Profile in db with name='{self.email}' - created")
instance.profile = obj
Obviously the Profile creation will be a side-effect of an import, so you may need to consider using transactions if you don't want Profiles created if the import fails.

ValueError at /spotify/liked/: Cannot assign 'some value': "Liked_Songs.track_name" must be a "Profile" instance

So I have users whose profiles are automatically created after user creation with the help of Django Signals
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
class Meta:
db_table = "Profile"
class Liked_Songs(models.Model):
track_name = models.ForeignKey(Profile , on_delete= models.CASCADE , related_name="track")
artiste_name= models.ForeignKey(Profile, on_delete= models.CASCADE , related_name="artiste")
album_name = models.ForeignKey(Profile, on_delete= models.CASCADE, related_name= "album")
class Meta:
db_table = "Liked Songs"
def __str__(self):
return self.track_name
In this Liked_Songs model, my views.py accesses an API and my aim is to allow all fields in that model to be populated with data from the API. So there will be multiple track_name etc received. So each Profile can have many track names etc. Is the ForeignKey appropriate for this?
However, when I use this route below, i get an error I have stated in the problem description.
Views.py
def liked(request):
try:
if "access_token" in request.session:
sp = Spotify(auth = request.session.get("access_token"))
liked = sp.current_user_saved_tracks(limit=30)['items']
for idx, item in enumerate(liked):
track = item['track']["name"]
artist= item["track"]["artists"][0]["name"]
album = item["track"]["album"]["name"]
Liked_Songs.objects.create(
track_name= track,
artiste_name= artist,
album_name = album
).save()
except SpotifyException:
return redirect(reverse("login"))
you are storing profile id in track so you cannot pass name in it so try to pass profile id in it
try this track_name_id = profile_id

How to get all inherited objects of a particular object of a model in django

I have these models:
class User(models.Model):
name = models.CharField(max_length=255)
email = models.EmailField(max_length=255)
class Manager(User):
experience_in_field_in_years = models.DecimalField(max_digits=5, decimal_places=2)
class SalesPerson(User):
current_hourly_rate = models.DecimalField(max_digits=5, decimal_places=2)
work_timings = models.CharField(max_length=255)
class Role(models.Model):
name = models.CharField(max_length=255)
class UserRole(models.Model):
user = models.ForeignKey("User", related_name="user_roles", on_delete = models.CASCADE)
Observer that User model is inherited by Manager, SalesPerson: there is a parent_link being generated as user_ptr_id to User table.
Now, whenever I create a manager/sales_person, a user is auto created.
A user can be both manager and sales_person. So, How to find/group a user with its child models? If I get a user from User, I need a way to know that he is a manager cum sales_person or only manager.
manager = Manager.objects.get(pk=2) #here 2 is actually the user id-> User model
manager.name #white
manager.experience_in_field_in_years #5
The above works. But,
user = User.objects.get(pk=2)
user.name #white
user.experience_in_field_in_years #error!! doesn't work. I want this to work.
Another query Should I use the Role, UserRole models? since I am already creating separate models for the respective roles?
You can check if the User object has a manager or salesperson attribute:
if hasattr(user, 'manager'):
# then object is a manager instance
if hasattr(user, 'salesperson'):
# then object is a salesperson instance
I suggest you take a look at the django extension polymorphic-models https://django-polymorphic.readthedocs.io/en/stable/
from polymorphic.models import PolymorphicModel
class User(PolymorphicModel):
name = models.CharField(max_length=255)
email = models.EmailField(max_length=255)
class Manager(User):
experience_in_field_in_years = models.DecimalField(max_digits=5, decimal_places=2)
class SalesPerson(User):
current_hourly_rate = models.DecimalField(max_digits=5, decimal_places=2)
work_timings = models.CharField(max_length=255)
Then user in the following code is a Manager instance
Manager.objects.create(name='manager')
user = User.objects.get(name='manager')

Is it possible to have a class as your model field in Django?

I am currently trying to create a health network website in Django.
The idea is that there will be a class called User inside my registration application. One of the states stored inside User is which hospital the user is registered into.
I created another Hospital within the registration app. I want to user that model Hospital as one of the model field for the hospital_used state. How do I do that? Below is a portion of my UML that illustrates the relationship
UML Diagram
Below is a portion of my UML that illustrates the relationship
png
Here is the code I have for it so far. The code where it is encapsulated with an asterisk is what I need help with.
class Hospital(models.Model):
hospital_Name = models.CharField(max_length=150)
def __str__(self):
return "Hospital Name: " + str(self.hospital_Name)
class User(models.Model):
PATIENT = 'Pat'
DOCTOR = 'Doc'
NURSE = 'Nurse'
ADMINISTRATOR = 'Admin'
user_type_choice = {
(PATIENT, 'Patient'),
(DOCTOR, 'Doctor'),
(NURSE, 'Nurse'),
(ADMINISTRATOR, 'Administrator'),
}
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
*preferred_hospital = Hospital(models.CharField(max_length=50))*
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
Thank you StackOverflow Buddies
I would advise you to read this material on tutorials on how to create simple models.
What you want here is to use the ForeignKey method.
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
preferred_hospital = models.ForeignKey(Hospital, on_delete = models.CASCADE)
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
You do not have to use on_delete = models.CASCADE but it is best that you handle what should happen when you delete an Hospital.
Know that you can also have OneToOne, ManyToOne, or ManyToMany fields, that are all described here.