I'm trying to create a ForeignKey relation to a postgres view. This was originally working with a different model but now that I've created a second one it seems unable to create the new table.
The error I'm given is:
DatabaseError: referenced relation "countryzone" is not a table
The Country model is defined as follows:
class Country(models.Model):
code = models.CharField(
db_column = 'countrycode',
primary_key = True,
max_length = 2,
)
name = models.CharField(
max_length = 100,
db_column = 'countryname',
unique = True,
)
language_code = models.CharField(
max_length = 8,
null = True,
)
country_level = models.IntegerField()
latitude = models.DecimalField(
db_column = 'clat',
decimal_places = 3,
max_digits = 8,
null = True,
)
longitude = models.DecimalField(
db_column = 'clong',
decimal_places = 3,
max_digits = 8,
null = True,
)
timezone = models.IntegerField()
zone = models.CharField(max_length=1)
transit_time = models.IntegerField()
## MANAGER
objects = CountryManager()
## META DATA
class Meta:
db_table = 'countryzone'
My new model creates the ForeignKey the following way:
country = models.ForeignKey(
to = 'location.Country',
db_column = 'countrycode',
)
I'm referencing the Country model from a different class without any problems like so:
countrycode = models.ForeignKey(
to = 'location.Country',
db_column = "countrycode",
)
Any ideas where I might be going wrong or what I should look into to find my problem?
Thanks!
the name of table must be location_countryzone.
Looks like syncdb can't handle this on it's own, I needed to use manage.py sqlall to get the correct query and run it myself. Once doing so the table was skipped over on future attempts of syncdb so then I was able to continue using it.
Related
I am working on a Django project and stuck at a problem. My models look like this:
class Products(models.Model):
basket_name = models.CharField(max_length = 5, blank = False)
product_name = models.CharField(max_length = 30, blank = False)
quantity = models.PositiveSmallIntegerField(null = False, blank = False, default=1)
class ShelfProduct(models.Model):
shelf_name = models.CharField(max_length = 15, default="defaultshelf")
products = models.ManytoManyField(Products)
..... other fields....
class KioskShelf(models.Model):
kiosk_name = models.CharField(max_length= 15, default="default")
shelfproduct = models.ManytoManyField(ShelfProduct)
...other fields....
class MapperModel(models.Model):
kioskshelf = models.ForeignKey(KioskShelf, on_delete = models.CASCADE)
...other fields....
I am trying to update the product quantity in Products models for a particular kiosk name and particular shelf. I tried like this:
data = MapperModel.objects.filter(kioskshelf__kiosk_name = 'kiosk1').filter(kioskshelf__shelfproduct__shelf_name = 'Shelf A')
But after this am not sure how to update the quantity in Products table. Am not even so sure if my approach is correct. Please assist me how to do it. Thanks a lot in advance.
You need to go through the Products table. Have you tried:
Products.objects.filter(shelfproduct__shelf_name='Shelf A', shelfproduct__kioskshelf__kiosk_name='kiosk1').update(quantity=<quantity>)
i want save a list of model in database table but i very slow
when i use save() method for each item it took near 20min
is that a best way to save objects to table
Modles.py
class Part(models.Model):
block = models.CharField(max_length= 2, null= True)
phase = models.CharField(max_length= 3, null= True)
department = models.CharField(max_length= 20, null= True)
type = models.CharField(max_length= 10, null= True)
mark = models.CharField(max_length= 20, null= True)
class Task(models.Model):
name = models.CharField(max_length= 20)
class ProjectTask(models.Model):
project = models.ForeignKey('Project', on_delete= models.CASCADE)
task = models.ForeignKey("Task", on_delete=models.CASCADE)
weight_percent = models.FloatField()
class PartTask(models.Model):
part = models.ForeignKey('Part', on_delete= models.CASCADE)
project_task = models.ForeignKey('ProjectTask', on_delete= models.CASCADE)
progress = models.FloatField(null=True)
views.py
def import_part_task(_project_id):
project_id = _project_id
project_task = ProjectTask.objects.all().filter(project= int(project_id[0]))
part_list = Part.objects.all()
part_task_list = []
for part in part_list:
for task in project_task:
part_task = PartTask()
part_task.part =part
part_task.project_task = task
part_task_list.append(part_task)
#This ACTION TAKES VERY LOG TIME
for part_task in part_task_list:
PartTask.save(part_task)
That makes perfect sense, since saving the database means that you each time query the database. This takes significant time.
You can however boost performance by inserting with bulk_create(..) [Django-doc]:
def import_part_task(_project_id):
project_id = _project_id
project_task = ProjectTask.objects.filter(project= int(project_id[0]))
part_list = Part.objects.all()
part_task_list = [
PartTask(part=part, project_task=task)
for part in part_list
for task in project_task
]
PartTask.objects.bulk_create(part_task_list)
By inserting in bulk, Django will create a query to insert a large amount of objects with a single query, instead of each time making a query for each individual PartTask object. The amount of "round trips" to the database is thus reduced significantly.
here is models.py
class Product(models.Model):
brand = models.ForeignKey(Brand , related_name='products')
category = models.ForeignKey('Category', verbose_name='categories', related_name='products' , default='')
parent = models.ForeignKey('self' , related_name = 'children' , null=True , blank=True)
title = models.CharField(max_length=500)
class StoreProduct(models.Model):
product = models.ForeignKey('products.Product')
category = models.ForeignKey('products.Category')
store = models.ForeignKey('Store')
class Store(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL , null=True , blank=True)
StoreName = models.CharField(max_length=50 , default = '')
items = models.ManyToManyField('products.Product', through=StoreProduct)
brand = models.ForeignKey('products.Brand' , null=True , blank=True)
City = models.CharField(max_length=50 , default = '')
Area = models.CharField(max_length=50 , default = '')
Address = models.TextField(max_length=500)
MallName = models.CharField(max_length=50 , null=True , blank=True)
slug = models.SlugField(blank=True ,unique=True)
here is views.py
queryset = StoreProduct.objects.all().distinct()
Multiple store can contain the same product and but they should appear once on the product grid page.Distinct query is not working.What can i do to show distinct values in the above case?Thanks in Advance
If you are using PostgreSQL, specify the level of distinction:
queryset = StoreProduct.objects.distinct('product')
you can also use it in conjunction with values(), order_by(), etc:
queryset = StoreProduct.objects.values('product').distinct()
I will suggest the following as solution but not the solution; either you choose PosgreSQL as database, specially that the newest Django version is coming with more built-in support for complex data structure, or you try make you own filter as follow (but in case you have large dataset this will be really bad):
store_product_id_list = StoreProduct.objects.values('product').distinct()
store_product_list = []
for obj in store_product_id_list:
store_product_obj = StoreProduct.objects.filter(product_id=obj.get('product')).first()
store_product_list.append(store_product_obj)
Check distinct for more examples
Model , with abstract base class:
class MapObject(models.Model):
start_date = models.DateTimeField(default= datetime.strptime('1940-09-01T00:00:00', '%Y-%m-%dT%H:%M:%S'))
end_date = models.DateTimeField(default= datetime.strptime('1941-07-01T00:00:00', '%Y-%m-%dT%H:%M:%S'))
description = models.TextField(blank=True)
location = models.PointField()
objects = models.GeoManager()
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add = True)
last_modified = models.DateTimeField(auto_now = True)
source = models.ForeignKey(Source)
address= models.TextField(blank=True, null=True)
address_road = models.TextField(blank=True, null=True)
class Meta:
abstract = True
class Bomb(MapObject, BombExtraManager):
#Bomb Attributes
type = models.CharField(choices= Type_CHOICES, max_length=10)
night_bombing = models.BooleanField(blank=True)
map_sheet = models.ForeignKey(MapSheet, blank=True, null=True)
def __unicode__(self):
return self.type
Now, I want to get the equivalent result using Django ORM as this query:
Select date_part('day',"start_date") as "day", date_part('hour',"start_date") as "hour", Count('id')
from "Mapper_bomb"
where "source_id" = 1
group by date_part('hour',"start_date"), date_part('day',"start_date")
Order by date_part('day',"start_date") ASC, date_part('hour',"start_date") ASC
Which would give me a table with the count of bombs per day and hour.
Using Django ORM, I have come to the following at the moment (first_day is just a custom manager I defined that returns a subset of the data, same as source_id = 1):
Bomb.first_day.extra(select={'date': "date_part(\'day\', \"start_date\")", 'hour': "date_part(\'hour\', \"start_date\")"}).values('date', 'hour').order_by().annotate(Count('date'), Count('hour'))
but Django complains FieldError: Cannot resolve keyword 'date' into field. Is there a way using Django ORM to get the desired result or do I need to fallback on raw sql?
Does this work?
Bomb.first_day.extra({
'date': "date_part(\'day\', \"start_date\")",
'hour': "date_part(\'hour\', \"start_date\")"
}).values('date', 'hour').order_by('date', 'hour').annotate(Count('id'))
class Town (models.Model):
name = models.CharField (max_length = 150,
verbose_name = _("Human settlement name"),
)
ref_town = models.ForeignKey ('self',
blank = True,
null = True,
verbose_name = _("Superior human settlement"),
help_text = _("Superior human settlement name (for subordinate settlements)"),
)
class CoalMine (models.Model):
name = models.CharField (max_length = 150,
verbose_name = _("Coal mine"),
help_text = _("Coal mine name"))
town = models.ForeignKey (Town,
default = 1,
verbose_name = _("town"))
I have a lot of towns im my data and I need to filter those which are unrelated with coal mines. Is there any solution?
Since Django 1.3 you can override SimpleListFilter to get it to do what you want.