Hi Stackoverflow people,
I have a model which contains projects with the corresponding geolocation:
class Project(models.Model):
name = models.CharField(_('Project Name'), max_length=100, null=True, blank=True)
geolocation = models.PointField(_('Project Location'))
...
In addition, another model is representing a shapefile with the country borders:
class WorldBorder(models.Model):
name = models.CharField(max_length=50)
mpoly = models.MultiPolygonField()
objects = models.GeoManager()
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
How can I do a query on Project and order the results by the country name of the geolocation?
A query like
d = Project.objects.all().order_by(geolocation__name)
does not work since geolocation is not a Foreignkey. Do I really have loop through all projects and determine the country manually like in my example below?
projects = Project.objects.all()
result = []
for project in projects
country = WorldBorder.objects.filter(mpoly__contains = project.geolocation)
foo = [project.name, country]
result.append(foo)
# now sort the list according to the country
result = sorted(result, key=itemgetter(1))
There should be a more professional and elegant solution? Any suggestions from the experienced Python people? Can I use joins for that purpose?
Thank you for your suggestions!
Related
I am fairly new to django and I am trying the following:
I am making an ordering web app for a nearby business. I am trying to add all the calories in a combo.
I have a model "Consumable", this represent the different food and drinks there are.
Here is the code for the "Consumable" Model:
class Consumable(models.Model):
name = models.CharField(max_length=80, unique=True)
category = models.ForeignKey(FoodCategory, null=True, on_delete=models.SET_NULL)
price= models.FloatField(default=0.00)
calories = models.IntegerField(blank=False)
image = models.ImageField(upload_to="images/Food/")
description = RichTextField(blank=True, max_length=500)
restaurant = models.ForeignKey(Place, on_delete=models.CASCADE)
added = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Then, I have a model called "Meal" which has the following code:
class Meal(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='images/photos/meals')
consumables = models.ManyToManyField(Consumable, related_name="consumable")
restaurant = models.ForeignKey(Place, on_delete=models.CASCADE)
price = models.FloatField()
def add_cals(meal_consumables):
total_calories = 0
for x in meal_consumables.values():
global total_calories += float(x.calories)
return total_calories
I am trying to call this model's function, add_cals from my HTML file using the DTL (Django Template Language).
For example, if you have a model stored with the variable x in your view, and it is in the view's context dictionary, you could simply call the model by using <p>{{x}}</p>, for example. And if the model has a variable x1, you could call it as <p>{{x.x1}}</p> and it works fine. However, if the x model from my example has a function
add_x(x):
return x
then it wouldn't work when you call it as <p>{{x.add_x(1)}}</p> for some reason. Could some wise individual out there in this world be so humble to share his or her knowledge with me in order to help me?
Thanks to everyone who tries.
So, I am learning Django and trying to make a site similar to AirBNB.
I have models called lisitngs that has latitude and longitude stored in CharField. My model is as follows:
class Listing(models.Model):
class BathRoomType(models.TextChoices):
ATTACHED = 'Attached Bathroom'
COMMON = 'Shared Bathroom'
class RoomVentType(models.TextChoices):
AC = 'Air Conditioner'
NO_AC = 'No Air Conditioner'
class LisitngType(models.TextChoices):
ROOM = 'Room'
APARTEMENT = 'Apartement'
HOUSE = 'Full House'
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
city = models.ForeignKey(RoomLocation, on_delete=models.CASCADE)
exact_address = models.CharField(max_length=255)
lat = models.CharField(max_length=300, blank=False, null=False, default="0")
lng = models.CharField(max_length=300, blank=False, null=False, default="0")
description = models.TextField()
price = models.IntegerField()
listing_type = models.CharField(max_length=20, choices=LisitngType.choices, default=LisitngType.ROOM)
kitchen_available = models.BooleanField(default=False)
kitchen_description = models.TextField(null=True, blank=True)
bedrooms = models.IntegerField()
max_acomodation = models.IntegerField()
bathroom_type = models.CharField(max_length=20, choices=BathRoomType.choices, default=BathRoomType.ATTACHED)
no_bathrooms = models.IntegerField()
room_type = models.CharField(max_length=30, choices=RoomVentType.choices, default=RoomVentType.AC)
main_photo = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_1 = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_2 = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_3 = models.ImageField(upload_to='room_images', default='default_room.jpg')
is_published = models.BooleanField(default=False)
date_created = models.DateTimeField(default=timezone.now, editable=False)
slug = AutoSlugField(populate_from=['title', 'listing_type', 'bathroom_type', 'room_type'])
rating = models.IntegerField(default=5)
approved = models.BooleanField(default=False)
total_bookings = models.IntegerField(default=0)
def __str__(self):
return self.title
In my homepage what I want to do is show the listings which are nearby me.
For that I have a function named as near_places. This near_place function takes latitude and longitude after querying through the model Listing and returns the distance between the listing and current user accessing the homepage:
import geocoder
from haversine import haversine
def near_places(dest_lat, dest_lng):
g = geocoder.ip('me')
origin = tuple(g.latlng)
destination = (dest_lat, dest_lng)
distance = haversine(origin, destination)
return distance
My homepage function in views.py is as follows:
def home(request):
objects = Listing.objects.filter(is_published=True, approved=True)
for object in objects:
lat, lng = float(object.lat), float(object.lng)
object.distance = near_places(lat, lng)
return render(request, 'listings/home.html')
As you can see I have looped through the query set and for each data I have calculated the distance and appended in the queryset as distance. Now, I would like to only get 10 items that has lowest distance. How, can I do so.
I have tried to user object = objects.order_by('-distance')[:10] but it gives me error as
FieldError at /
Cannot resolve keyword 'distance' into field. Choices are: The_room_booked, approved, bathroom_type, bedrooms, city, city_id, date_created, description, exact_address, id, is_published, kitchen_available, kitchen_description, lat, listing_type, lng, main_photo, max_acomodation, no_bathrooms, photo_1, photo_2, photo_3, price, rating, reviewsandrating, room_type, slug, title, total_bookings, user, user_id
Any way that I can solve it?
Also it takes quite a time to calculate current distance using near_places() function as above. Any suggestions will be helpful.
Thank You
You can't do that, because your model doesn't have a distance field and there is no such DB column as well.
What you can do is either
add such field to your model - I don't recommend with your current logic as you will iterate over every instance and send sql request to update every row.
get your queryest, convert it to a list of dicts and then iterate over your list of dicts with your function adding the distance key to it. Then you can sort the list by the python sort function and pass it to the template.
Like:
objects = Listing.objects.filter(is_published=True, approved=True).values('lat', 'lng') # add fields that you need
for obj in objects:
obj['distance'] = near_places(obj['lat'], obj['lng'])
my_sorted_list = sorted(objects, key=lambda k: k['distance'])
Pass my_sorted_list to your template. You can add reverse=True arg to sorted function if you want another direction sorting.
I'm making a program that helps log missions in a game. In each of these missions I would like to be able to select a number of astronauts that will go along with it out of the astronauts table. This is fine when I only need one, but how could I approach multiple foreign keys in a field?
I currently use a 'binary' string that specifies which astronauts are to be associated with the mission (1 refers to Jeb, but not Bill, Bob, or Val and 0001 means only Val), with the first digit specifying the astronaut with id 1 and so forth. This works, but it feels quite clunky.
Here's the model.py for the two tables in question.
class astronauts(models.Model):
name = models.CharField(max_length=200)
adddate = models.IntegerField(default=0)
experience = models.IntegerField(default=0)
career = models.CharField(max_length=9, blank=True, null=True)
alive = models.BooleanField(default=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Kerbals"
class missions(models.Model):
# mission details
programid = models.ForeignKey(programs, on_delete=models.SET("Unknown"))
missionid = models.IntegerField(default=0)
status = models.ForeignKey(
missionstatuses, on_delete=models.SET("Unknown"))
plan = models.CharField(max_length=1000)
# launch
launchdate = models.IntegerField(default=0)
crewmembers = models.IntegerField(default=0)
# recovery
summary = models.CharField(max_length=1000, blank=True)
recdate = models.IntegerField(default=0)
def __str__(self):
return str(self.programid) + '-' + str(self.missionid)
class Meta:
verbose_name_plural = "Missions"
I saw a post about an 'intermediate linking table' to store the crew list but that also isn't ideal.
Thanks!
This is the use case for Django's ManyToManyField. Change the appropriate field on the missions:
class missions(models.Model):
crewmembers = models.ManyToManyField('astronauts')
You can access this from the Astronaut model side like so:
jeb = astronaut.objects.get(name='Jebediah Kerman')
crewed_missions = jeb.missions_set.all()
Or from the mission side like so:
mission = missions.objects.order_by('?')[0]
crew = mission.crewmembers.all()
This creates another table in the database, in case that is somehow a problem for you.
I'm working on a web for translators. I'm stucked on designing a structure of the data. So there is a model Translator, Language and Level. The price depends on Language and Level (Standard level multiplies the price 1x, Professional 1.5x etc.)
Each Translator can translate multiple languages with different levels (skills).
I can't figure out how to design models for this purpose. My idea is to store for each Translator some field of tuples (Language,Level) so the model Translator would be:
class TranslatorProfile(models.Model):
user = models.OneToOneField(User, related_name='userprofile')
date_of_birth = models.DateField(null=True,blank=True)
telephone = models.CharField(max_length=40,null=True,blank=True)
IBAN = models.CharField(max_length=40,null=True,blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
# HERE IS THE PROBLEM
languages = models.FieldOfModelTuples(Language,Level)
class Level(models.Model):
LEVEL_NAMES = (
('standard', 'Standard'),
('professional', 'Professional'),
#etc.
)
name = models.CharField(max_length=40, choices=LEVEL_NAMES)
price_multiplier = models.FloatField()
class Language(models.Model):
shortcut = models.CharField(max_length=40)
name = models.CharField(max_length=40)
def __str__(self):
return self.name
I would appreciate any advice how to solve this problem (.FieldOfModelTuples does not exists of course). Maybe there is a simpler way to do this.
I think that Level should be a field on a through-model for a many-to-many relationship between TranslatorProfile and Language:
class TranslatorLanguage(models.Model):
translator = models.ForeignKey('app_name.TranslatorProfile')
language = models.ForeignKey('app_name.Language')
level = models.ForeignKey('app_name.Level')
class Meta:
unique_together = (('translator', 'language'),)
this allows you to query all necessary properties for each Translator-Language pair. Access to a translator's languages can then be simplified via:
# HERE IS THE PROBLEM
languages = models.ManyToManyField(Language, through='TranslatorLanguage')
Hi i'm not very good at English but i'll try to explain myself the best i could. I'm using python and Django to create a web project.
I have this 4 models (this is the best translation i can do of the tables and fields):
class Humans (models.Model):
name = models.CharField(max_length=15)
surname = models.CharField(max_length=15)
doc_num = models.CharField(max_length=11)
...
class Records (models.Model):
closing_state = models.CharField(max_length=2)
...
humans = models.ManyToManyField(Humans, through='Reco_Huma')
class Reco_Huma (models.Model):
id_record = models.ForeignKey(Records)
id_human = models.ForeignKey(Humans)
categorys = models.CharField(max_length=2)
reserv_identity = models.CharField(max_length=2)
repre_entity = models.CharField(max_length=2)
class Observations (models.Model):
id_record = models.ForeignKey(Records)
text = models.CharField(max_length=80)
category = models.CharField(max_length=2, choices=CAT)
Now given a doc_num from Humans, a text from Observations i want to get a QuerySet Of all the Records.
To clarify i first do this:
q1 = Reco_Huma.objects.filter(id_human.doc_num=x)
q2 = Observations.objects.filter(text=y)
both query-sets give me a list of id_record and then i want to connive that lists and filter the Records table with that id_record's
I hope you can understand me
Thanks in advance
To rephrase your query, you want all the Records associated with a certain Human and which have a certain Observation. So it should be:
result = Records.objects.filter(observations__text=y, humans__doc_num=x)
As a general rule, if you want to end up with a certain type of object, it helps to start from there in your query.