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()
Related
Query
TechnicianAssignment.objects.filter(Q(slot__slot_date=curr_datetime.date())&Q(assigned_technician__attendance_Technician__attendance_status__in=['Rejected', 'Absent', 'Someone else reported', 'Present']))
Models in short:
**Table 1**:
class TechnicianTeam(models.Model):
id = models.AutoField(primary_key=True)
supervisor = models.ForeignKey('self', null=True, blank=True, related_name="TechnicianSupervisor", on_delete=models.DO_NOTHING)
customer_profile = models.ForeignKey('login.CustomerProfile',
related_name="technician_TeamUser", on_delete=models.DO_NOTHING)
class Meta:
db_table = "technician_team"
**Table2:**
class TechnicianAssignment(models.Model):
id = models.AutoField(primary_key=True)
slot = models.ForeignKey('technician_management.TechnicianSlot',
related_name="assignment_Slot", on_delete=models.DO_NOTHING)
assigned_technician = models.ForeignKey('technician_management.TechnicianTeam',
related_name="assignment_Technician", on_delete=models.DO_NOTHING)
class Meta:
db_table = "technician_assignment"
**Table3**
ATTENDANCE_CHOICES = [
('Rejected','Rejected'),
('Someone else reported','Someone else reported'),
('Absent','Absent'),
('Present','Present')
]
class TechnicianAttendance(models.Model):
id = models.AutoField(primary_key=True)
technician = models.ForeignKey('technician_management.TechnicianTeam',
related_name="attendance_Technician", on_delete=models.DO_NOTHING)
slot = models.ForeignKey('technician_management.TechnicianSlot',
related_name="attendance_Slot", on_delete=models.DO_NOTHING)
attendance_status = models.CharField(max_length=30, choices=ATTENDANCE_CHOICES, null=True)
class Meta:
db_table = "technician_attendance"
Question what is wrong with my query:
I need to filter out from TechnicianAssignment where in entries were "slot__slot_date" is current date and "__attendance_Technician__attendance_status__in" = ['Rejected', 'Absent', 'Someone else reported', 'Present']
there is only 1 entry in db with attendance status 'Present' but i am getting many output because of "__attendance_Technician__attendance_status__in" this filter.
I have a functioning search function shown below, it works without issue. We are redesigning the system, the area_easting value now sits in its own table (model). To get to the area_easting he route is as follows: Trench.trench_id --> Context.context_id --> Sample.sample_id (I know this is non-standard notation).
So how would I traverse these joins? Something like:
qs = qs.filter(sample_id__context_id__trench_id__area_easting__icontains=easting_query)
Which returns Unsupported lookup 'context_id' for AutoField or join on the field not permitted.
from excavation.models import Trench, Context, Sample
from ceramic.models import Ceramic
...
def CeramicFliterView(request):
qs = Sample.objects.all()
easting_query = request.GET.get('area_easting')
if easting_query != '' and easting_query is not None:
qs = qs.filter(area_easting__icontains=easting_query)
...
Models.py
class Trench(models.Model):
trench_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=500, default='', blank=True, null=True)
area_easting = models.IntegerField()
area_northing = models.IntegerField()
...
class Context(models.Model):
context_id = models.AutoField(primary_key=True)
trench_id = models.ForeignKey(Trench, db_column='trench_id', on_delete = models.PROTECT)
...
class Sample(models.Model):
sample_id = models.AutoField(primary_key=True)
context_id = models.ForeignKey(Context, db_column='context_id', on_delete = models.PROTECT)
...
class Ceramic(models.Model):
ceramic_id = models.AutoField(primary_key=True)
sample_id = models.ForeignKey(Sample, db_column='sample_id', on_delete = models.PROTECT)
I have these classes -
class DocumentType(models.Model):
type_id = models.AutoField(primary_key=True)
name = models.CharField('type name', max_length=200)
class MetaData(models.Model):
metadata_id = models.AutoField(primary_key = True)
name = models.CharField('metadata name', max_length=200, unique=True)
description = models.TextField('description')
class DocumentTypeMetaData(models.Model):
documentType_id = models.ManyToManyField(DocumentType,)
metadata_id = models.ManyToManyField(MetaData,)
required = models.BooleanField(default=False)
For example, a DocumentType value of 'Photo' would have Required Metadata of 'Decade' and 'Orientation'.
In the DocumentTypeMetaData class I would like to have a def __str__(self) function that returns something like the following in the admin page -
Photo: (Decade, Photo Type) required
The format is not critical, I just want to know which metadata is required. Currently, all that is displayed is
DocumentTypeMetaData object
on the admin page.
I am struggling with how to write the queries for this function.
Thanks!
Mark
These relationships are not right. The many-to-many relationship is between DocumentType and MetaData; DocumentTypeMetaData is the through table. So:
class DocumentType(models.Model):
type_id = models.AutoField(primary_key=True)
name = models.CharField('type name', max_length=200)
metadata = models.ManyToManyField('MetaData', through='DocumentTypeMetaData')
class MetaData(models.Model):
metadata_id = models.AutoField(primary_key = True)
name = models.CharField('metadata name', max_length=200, unique=True)
description = models.TextField('description')
class DocumentTypeMetaData(models.Model):
document_type = models.ForeignKey(DocumentType)
metadata = models.ForeignKey(MetaData)
required = models.BooleanField(default=False)
def __str__(self):
return '{} {} {}'.format(self.document_type, self.metadata, self.required)
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.
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).