Django find common instances data in two models - django

I have models like:
class Hospital(models.Model):
name = models.CharField(max_length=200, unique=True)
manager_name = models.CharField(max_length=200, default='')
manager_id = models.CharField(max_length=200)
def __str__(self):
return f'{self.name}'
class Sick(models.Model):
name = models.CharField(max_length=200, default='')
nationalID = models.CharField(max_length=200)
illName = models.CharField(max_length=200)
hospital = models.ForeignKey(Hospital, related_name='sicks', on_delete=models.DO_NOTHING)
def __str__(self):
return f'({self.name}, {self.nationalID})'
class Employee(models.Model):
name = models.CharField(max_length=200, default='')
nationalID = models.CharField(max_length=200)
company = models.ForeignKey(Company, related_name='employees', on_delete=models.CASCADE)
def __str__(self):
return f'({self.name}, {self.nationalID})'
views:
#api_view(['POST'])
def get_sick_employee_by_hospital(request):
pass
and a serializer like :
from rest_framework import serializers
class NameSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=200, allow_null=False)
my problem is :
my view get_sick_employee_by_hospital() receives a hospital name and it must return all sick peoples that are employees and They have visited that hospital, in a dictionary with keys 1,2,3,..., n and values like "(name, nationalID)".
Pay attention that it does not matter which value is assigned to which key.
What is the best way to do that ? how can i get all sick peoples that are employees and They have visited a hospital?

Related

Error for my model with ManyToManyField in Django

I am working for a personal project that is using an API and having user authentication with JWT (but used in serializer). I wanted to implement ManyToManyField for user and city but it doesn't work properly. This is the extended model I have found and django aggregation . I want that the UserSearchLocation to store the City and when logged in to see the city, while other users will not see it until the search same city.
models.py
class UserSearchLocation(models.Model):
city_name = models.CharField(max_length=85, blank=False)
def __str__(self):
return self.city_name
class City(models.Model):
user_searched_locations = models.ManyToManyField(User,
through='UsersLocations',
through_fields=('city', 'user'),
related_name="my_cities",
blank=True)
id = models.AutoField(primary_key=True, editable=False)
location = models.CharField(max_length=85)
country = models.CharField(max_length=85, blank=True)
country_code = models.CharField(max_length=2, blank=True)
latitude = models.DecimalField(max_digits=6, decimal_places=4,
null=True, blank=True)
longitude = models.DecimalField(max_digits=6, decimal_places=4,
null=True, blank=True)
zip_code = models.PositiveIntegerField(default=0)
#users_location = models.ManyToManyField(UserSearchLocation)
def __str__(self):
return f'{self.location}, {self.country_code}'
def save(self, *args, **kwargs):
self.location = self.location.capitalize()
self.country = self.country.capitalize()
self.country_code = self.country_code.capitalize()
return super(City, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = 'cities'
unique_together = ("location", "country_code")
class UsersLocations(models.Model):
id = models.AutoField(primary_key=True, editable=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
city = models.ForeignKey(City,
on_delete=models.CASCADE,
related_name='locations_by_users',
null=True)
To add in localhost/admin/ a City works, but when to add a UserSearchLocation I have this error:
Exception Value:
column base_usersearchlocation.user_id does not exist
LINE 1: SELECT "base_usersearchlocation"."user_id", "base_usersearch...
Your error says the city.location doesn't exist - location is a CharField on your City model - are you sure you've run migrations and don't have any naming conflicts?

Related fields on model?

There is a model ElectoralTable
class ElectoralTable(models.Model):
name = models.CharField(max_length=250)
country_owner = models.ForeignKey(Country, on_delete=models.CASCADE)
city_owner = models.ForeignKey(City, on_delete=models.CASCADE)
address = models.CharField(max_length=400)
latitude = models.CharField(max_length=250, blank=True)
longitude = models.CharField(max_length=250, blank=True)
class Country(models.Model):
name = models.CharField(max_length=250, unique=True, blank=False)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class City(models.Model):
name = models.CharField(max_length=400, blank=True)
country_owner = models.ForeignKey(Country, on_delete=models.CASCADE, related_name='country')
def __str__(self):
return self.name
class Meta:
ordering = ('country_owner', 'name', )
How can I to select a city related to a country. Rigth now I receive every city on Model City but I want only to receive the cities related wiht country owner
Well I found one solution to prevent save a city who doesn't belong to country it was to overwrite the clean method
def clean(self):
city = City.objects.filter(country_owner__name=self.city_owner)
city_names = []
for item in city:
city_names.append(item.name)
if not str(self.city_owner) in city_names:
raise ValidationError(_('The city doesn't belong to the country'))

Add Depandent drop down list for Django admin user

I have created 4 models in my django Country, State, and City, and also add them in admin.site.register How Can I add dependent drop down list for Country State City for admin user whenever user try to create Aplications object, they get state name list depends on Country name selected by admin user, and also for city.
Models.py
from django.db import models
from django.db.models import ForeignKey
from multiselectfield import MultiSelectField
class Country(models.Model):
name = models.CharField(max_length=250)
phone_code = models.CharField(max_length=250)
currency = models.CharField(max_length=250)
def __str__(self):
return self.name
class State(models.Model):
name = models.CharField(max_length=250)
country = models.ForeignKey(to=Country, on_delete=models.CASCADE)
def __str__(self):
return self.name
class City(models.Model):
state = models.ForeignKey(to=State, on_delete=models.CASCADE)
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Applications(models.Model):
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
state = models.ForeignKey(State, on_delete=models.SET_NULL, null=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=20)
phone_number = models.IntegerField()
email_id = models.EmailField()
home_address = models.CharField(max_length=255, blank=True, null=True)
birthdate = models.DateField(null=True, blank=True)
current_company = models.TextField(max_length=250, blank=True, null=True)
def __str__(self):
return str(self.name)
they get state name list depends on Country name selected by admin user, and also for city
Since you said a dropdown list, I will suggest switching over to a multiple choice field where the choices will be set to a certain range of values and will appear as a dropdown in the admin dashboard.

How get information from three different tables at once?

I have following models:
class Device(models.Model):
name = models.CharField(max_length=100, blank=False)
description = models.TextField(max_length=500, blank=True)
ip_address = models.GenericIPAddressField(blank=True, null=True)
contact_person = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
class TimeSlot(models.Model):
name = models.CharField(max_length=20)
start_slot = models.CharField(max_length=10)
end_slot = models.CharField(max_length=10)
def __str__(self):
return self.name
class Reservation(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
date_of_reservation = models.DateField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return "{} - {} for device: {} by {}.".format(self.time_slot, self.date_of_reservation, self.device, self.user)
class ForbiddenSlot(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
def __str__(self):
return str(self.time_slot)
This is simple reservation system. I have problem to understand how create query for three different tables.
I want get all TimeSlots which are not set in ForbiddenSlot and Reservation for given Device name.
I'm not entirely sure if this will work, but I think it will and is definitely worth a shot.
TimeSlot.objects.filter(
forbiddenslot__isnull=True,
reservation__device__name='Device Name',
)
It's not necessarily the easiest thing for me to wrap my head around, but not only does TimeSlot have access to .forbiddenslot_set, it also can filter by forbiddenslot. The same goes for reservation.
I guess changing the structure of your models will be much better, like deleting the model ForbiddenSlot and replacing it with a flag on the reservation model, then you can select all TimeSlots from the reservation model where the forbidden flag is False, like:
reservations = Reservation.objects.only('time_slot').filter(device__name=name_of_the_device,forbidden=False) where forbidden is a boolean field.
Using select_related() will pre-populate the appropriate attributes:
Model.objects.select_related()

Django Model design for a basic inventory application

I am new to Django (and databases for that matter) and trying to create a simple inventory application to help learn. I've been through the tutorials and am going through some books, but I am stuck at what i think is simple, just not sure where to look or how to ask.
With an inventory application, you have your equipment which then has a manufacturer, which the equipment has a model number that only that manufacturer has. Lets say Dell Optiplex 3040. I am also using the admin console right now as well. So i would like to be able to relate equipment to a manufacturer and then also relate the equipment to the model number. It almost seems as I am needing to use the many to many field and the through field to accomplish what I am trying to do but I dont think that is the right way to do it (shown in the link below). https://docs.djangoproject.com/en/1.9/topics/db/models/#many-to-many-relationships
Below is the code I have so far. Thank you.
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
equipmentModel = models.CharField(max_length=50)
def __str__(self):
return self.equipmentModel
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
***Edit to add the updated code and the admin.py code in response question I had to answer.
#admin.py
from django.contrib import admin
# Register your models here.
from .models import Device,Department,Manufacturer,Employees, Job_Positions, EquipmentModel
class DeviceModelAdmin(admin.ModelAdmin):
list_display = ["ip", "department","model","serial_number","date_updated"]
list_filter = ["department","model","ip"]
search_fields = ["ip"]
class Meta:
model = Device
class EmployeesModelAdmin(admin.ModelAdmin):
list_display = ["employee_name_first", "employee_name_last", "employee_username", "phone"]
list_filter = ["department"]
class Meta:
model = Employees
admin.site.register(Device, DeviceModelAdmin)
admin.site.register(Department)
admin.site.register(Manufacturer)
admin.site.register(EquipmentModel)
admin.site.register(Employees, EmployeesModelAdmin)
admin.site.register(Job_Positions)
updated models.py
from django.db import models
# Create your models here.
class Department(models.Model):
department = models.CharField(max_length=50)
def __str__(self):
return self.department
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=50)
def __str__(self):
return self.manufacturer
class EquipmentModel(models.Model):
model_number = models.CharField(max_length=50)
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
def __str__(self):
return self.model_number
class Employees(models.Model):
employee_name_first = models.CharField(max_length=25)
employee_name_last = models.CharField(max_length=25)
employee_username = models.CharField(max_length=20)
phone = models.IntegerField()
assigned_equipment = models.ForeignKey('Device', default='undefined')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default='undefined')
job_title = models.ManyToManyField('Job_Positions', default='undefined')
def __str__(self):
return self.employee_username
class Device(models.Model):
ip = models.GenericIPAddressField(protocol='IPv4',unpack_ipv4=False,null=True, blank=True)#might be good to seperate IP in its own class because a device can have multiple IP's
department = models.ForeignKey('Department', on_delete=models.CASCADE)
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE,null=True)
serial_number = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now=False, auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
comments = models.TextField(blank=True)
def __str__(self):
return self.serial_number
class Job_Positions(models.Model):
position_title = models.CharField(max_length=50)
position_description = models.TextField(blank=True)
def __str__(self):
return position_title
A many-to-many relationship is not what you want here, because any piece of equipment (I assume) can only have one manufacturer.
You do need an intermediate model which stores the model information, and you already have one in your EquipmentModel. I would suggest modifying it as follows:
class EquipmentModel(models.Model):
# This stores information about a particular model of device
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
model_number = models.CharField(max_length=50)
And then instead of having a foreign key to the manufacturer in Device, replace it with a foreign key to the equipment model:
class Device(models.Model):
# ...
model = models.ForeignKey('EquipmentModel', on_delete=models.CASCADE)