Django: Query involving Foreign Key - django

I have models.py
class employees(models.Model):
emp_id=models.PositiveIntegerField()
emp_name = models.CharField(max_length = 100)
emp_lname = models.CharField(max_length = 100)
emp_loc=models.CharField(max_length=5,choices=LOCATION)
manager_id=models.ForeignKey('self',null=True,blank=True)
class leave(models.Model):
employee = models.ForeignKey(employees, on_delete=models.CASCADE, default='1')
start_date = models.DateField()
end_date = models.DateField()
status=models.CharField(max_length=1,choices=LEAVE_STATUS,default='P')
ltype=models.CharField(max_length=2,choices=LEAVE_TYPE)
class notify(models.Model):
sender_id=models.ForeignKey(leave, related_name='%(class)s_sendername')
receiver_id=models.ForeignKey(leave,related_name='%(class)s_receivername')
date_time=models.DateTimeField(auto_now_add=True)
viewed=models.CharField(max_length=2)
I want the employee id of receiver_id as receiver_id is a foreign key...
When I query
notify.objects.filter(receiver_id__employee__emp_id=1)
I am getting empty queryset but I want the tuples with emp_id=1.

here notify.objects.filter(receiver_id__employee__emp_id=1) Make sure you have assigned emp_id field as it's not auto incremented field.
also try
notify.objects.filter(receiver_id__employee__id=1)

Related

how can i use django filter with multiple value select

I want to filter my data based on city , how can i filter my data if the user choose more than one city using django filter
class games(generics.ListAPIView):
queryset = Game.objects.filter(start_date__gte=datetime.today())
serializer_class=GameSerializers
filter_backends = [DjangoFilterBackend,filters.OrderingFilter]
filterset_fields = ['id','city','level']
game model
class Game(models.Model):
city = models.CharField(max_length=255)
gender = models.ForeignKey(Gender,on_delete=models.CASCADE)
level = models.ForeignKey(Level,on_delete=models.CASCADE)
host = models.ForeignKey(Host,on_delete=models.CASCADE)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
fees = models.IntegerField()
indoor = models.BooleanField()
capacity = models.IntegerField()
age_from = models.IntegerField()
age_to = models.IntegerField()
description = models.CharField(max_length=255)
earned_points = models.IntegerField()
created_at = models.DateTimeField(default=django.utils.timezone.now)
image = models.ImageField(upload_to="GameImage",null=True)
history = HistoricalRecords()
Game.objects.filter(city__in=['Paris', 'London'])
Something like that ?
I'm not sure if this gonna work but try this:
filterset_fields = ['id','city__in','level']

Django Nonetype object has no attribute 'id'

I want create product element and redirect to him page
def newprodcreate(request, c_id):
if models.company.objects.get(email = request.user.username).id == int(c_id):
name = request.POST['newprodname']
comp = models.company.objects.get(id = int(c_id))
prod = models.product()
prod.name = name
prod.comp_id = int(c_id)
prod.address = comp.address
prod.lat = comp.lat
prod.lng = comp.lng
prod.phone = comp.phone
prod.cur_id = 2
prod.save()
return HttpResponseRedirect("/p/" + str(prod.id))
the element created in database, but prod.id is Null
model:
class product(models.Model):
class Meta:
db_table = "product"
id = models.IntegerField(primary_key=True)
crdate = models.DateTimeField(default = datetime.now())
comp_id = models.IntegerField()
categ = models.CharField(max_length=200, default="")
img = models.FileField(upload_to=MEDIA_ROOT +"/product/", max_length=200)
name = models.CharField(max_length=200)...
Dear michael in django ORM for creating autho field or serial field which used for id primary key or etc we use Autofield instead of integer field .
id = models.AutoField(primary_key=True)
your model in corrected state:
class product(models.Model):
class Meta:
db_table = "product"
id = models.AutoField(primary_key=True)
crdate = models.DateTimeField(default =
datetime.now())
comp_id = models.IntegerField()
categ = models.CharField(max_length=200, default="")
img = models.FileField(upload_to=MEDIA_ROOT. +"/product/", max_length=200)
name = models.CharField(max_length=200)...
For django models There will be a default field with name "id" which is auto increment field. you have override that id with IntegerField that is id = models.IntegerField(primary_key=True)
So you have to provide id explicitly every time when you create product object
Better solution is to change id IntegerField to AutoField
id = models.AutoField(primary_key=True)
Then your id will be created automatically no need to pass id every time you create new object.

Filtering on foreign key table's attribute

These are my relevant models..
class Books(models.Model):
name = models.CharField(max_length=120)
author = models.CharField(max_length=120)
edition = models.CharField(max_length=120)
class Meta:
unique_together = ('name', 'edition',)
def __str__(self):
return self.name
class Items(models.Model):
book = models.ForeignKey(Books)
seller = models.ForeignKey(User,related_name = 'item_seller')
buyer = models.ForeignKey(User, related_name = 'item_buyer', null=True,blank= True)
requestee = models.ManyToManyField(User,related_name = 'item_requestee',blank= True)
cost_price = models.DecimalField(max_digits=8, decimal_places=2)
sale_price = models.DecimalField(max_digits=8, decimal_places=2)
sold = models.BooleanField(default=False)
date_added = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return self.book.name
And this is the part in view fuction where I am trying to filter on foreign key table's attribute
book_item = Items.objects.filter(book__name==q)
Where q is a string a get from user.
But I am getting error - book__name not defined. What am I doing wrong ?
You are using a boolean operator foo==bar where you should be using an assignment operator foo=bar.
Don't do:
book_item = Items.objects.filter(book__name==q)
Instead do:
book_item = Items.objects.filter(book__name=q)
When calling filter you want it to look through all the Items that have been created and return the Items that have a Book that has a name = (equal) to q (or what ever search variable you're looking for).

Fetch data from multiple tables in django views

In Django views, I want to fetch all details(Workeraccount.location,Workeravail.date, Workerprofile.*) for any particular wid=1.
SQL Query:
select * from Workeraccount,Workeravail,Workerprofile where Workerprofile.wid=1 and Workerprofile.wid=Workeravail.wid and Workeraccount.wid=Workerprofile.wid;
The corresponding models are as follows:
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True)
location = models.ForeignKey(Location, db_column='location')
class Meta:
managed = False
db_table = 'workerAccount'
class Workeravail(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid')
date = models.DateField()
class Meta:
managed = False
db_table = 'workerAvail'
class Workerprofile(models.Model):
wid = models.SmallIntegerField(primary_key=True)
fname = models.CharField(max_length=30)
mname = models.CharField(max_length=30, blank=True, null=True)
lname = models.CharField(max_length=30)
gender = models.CharField(max_length=1)
age = models.IntegerField()
class Meta:
managed = False
db_table = 'workerProfile'`
You can do this:
workprofile = Workerprofile.objects.filter(id=1).first()
all_worker_avails = workprofile.workeravail_set.all()
all_workeraccounts = workprofile.workeraccount_set.all()
As Workeraccount and Workeravail are related through Workerprofile, you can get one queryset easily - you will need two separate ones.
You can also do the following:
all_worker_avails = Workeravail.objects.filter(wid=workprofile)
...
Here is how you can do it with only one database call:
workprofile = Workerprofile.objects.get(pk=1)
.select_related('workeravail_set', 'workerprofile_set')
This will fetch all the data for you at once, which can then be used with:
workprofile.workerprofile_set.location #Gets the Workeraccount.location
workprofile.workeravail_set.date #Gets the Workeravail.date
workprofile.fname #Example of Workerprofile.*
As an aside, if you want a shorter way to reference the foreign objects than the "*_set" method, you can set a related_name like
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True, related_name='waccount')
...
And then replace workeraccount_set with waccount

django: getting foreign key information

I created a model with couple of classes and with foreign key and I was able to save it on the database.
I have the following models:
class Player_Bios(models.Model):
my_id = models.SlugField(unique=True)
player_id = models.IntegerField(max_length=50, unique=True)
name = models.CharField(max_length=50)
last = models.CharField(max_length=50)
middle = models.CharField(max_length=50, blank=True)
class BatStat (models.Model):
player_id = models.ForeignKey('Player_Bios')
team_id = models.ForeignKey('Team')
bat_stat_id = models.CharField(max_length=50, unique=True)
sport_code = models.CharField(max_length=50, blank=True)
ab = models.IntegerField(max_length=50, null=True)
class Team (models.Model):
team_id = models.IntegerField(max_length=50, unique=True)
team_short = models.CharField(max_length=50, blank=True)
team_full = models.CharField(max_length=50, blank=True)
When I save it to the database I can see that the team_id on the Team table is the same as the team_id on the BatStat table, but the player_id on the BatStat is different that the player_id on the Player_Bios table. This is how I save the data to the database:
p_id = Player_Bios.objects.get(player_id=st['player_id'])
t_id = Team.objects.get(team_id=st['team_id']) #I get the team_id from the Team Class
bat_id = str(st['season'])+ str(st['team_seq'])
bat_id = str(p_id.player_id) + bat_id
c = BatStat(player_id = p_id,team_id=t_id, bat_stat_id=bat_id, sport_code =st["sport_code"],ab=st['ab'])
c.save()
st['player_id'] is a dictionary. I did a print and it show the right player_id number
In BatStat you are storing the key to Player_Bios, which is not player_id
class Player_Bios(models.Model):
...
player_id = models.IntegerField(max_length=50, unique=True)
class BatStat (models.Model):
...
player_id = models.ForeignKey('Player_Bios')
I'm not sure why your team_id is the same, however, it seems like you already have the ids. You could avoid looking up the Player_Bios and Team by setting the id directly.
Django: Set foreign key using integer?
class Player_Bios(models.Model):
...
player_id = models.IntegerField(primary_key=True, max_length=50)
class Team (models.Model):
...
team_id = models.IntegerField(primary_key=True, max_length=50)
class BatStat (models.Model):
...
player = models.ForeignKey('Player_Bios') # notice i renamed this to not have '_id'
team = models.ForeignKey('Team') # notice i renamed this to not have '_id'
c = BatStat(bat_stat_id=bat_id,
sport_code =st["sport_code"],
ab=st['ab'])
c.player_id = st['player_id'], # notice that this has '_id'
c.team_id = st['team_id'], # notice this has '_id'
c.save()