I have a list (QuerySet of 'DailyEnrollment' objects) of dictionaries that looks like this:
[
{'location_id': 1, 'student_count': 780},
{'location_id': 4, 'student_count': 535},
{'location_id': 6, 'student_count': 496}
]
There is a Location
object which has an attribute name
- the location_id
in this list, correlates to a Location
object but it is not a foreign key (in the models) due to how other apps interact with this in our project.
Is there a simple way to iterate across this list, get each dictionaries location.name
for the location_id
and append it to the dictionary as location_name
?
I was considering a dictionary comprehension inside of a list comprehension - but I wasn't sure how Pythonic that was.
Models:
class Location(models.Model):
name = models.CharField(max_length=50)
short_name = models.CharField(max_length=50)
The DailyEnrollment is data nabbed from a view built with external data
class DailyEnrollment(SchoolModel):
id = models.IntegerField(db_column='ID', primary_key=True)
location_id = models.IntegerField(db_column='schoolID')
grade = models.CharField(db_column='grade', max_length=10)
end_year = models.IntegerField(db_column='endYear')
run_date = models.DateField(db_column='runDate')
student_count = models.IntegerField(db_column='studentCount')
In the view this is how I get my Daily Enrollments
# get past enrollments
past_daily_enrollments = DailyEnrollment.objects.filter(
run_date=datetime.strptime(since_date, '%m-%d-%Y'),
location_id__lte='31',
end_year='2018')
I create a 'new list' of data with everything grouped on location_id
, with the total student_count
location_data = past_daily_enrollments.values('location_id').annotate(
student_count=Sum('student_count')
)
That's how I get to the issue I asked about. I have 'location_data', which is my list of dictionaries.
Your models are not correct. I suspect that they were produced by running inspectdb
against an existing database; one of the issues with doing that is that it is occasionally unable to detect foreign keys. In your case however, location_id
is clearly a foreign key to Location, so you should declare it as such:
location = models.ForeignKey('Location', db_column='schoolID')
Once you have done that, you can simply follow the relationship via the double-underscore syntax in your values call:
past_daily_enrollments.values('location__name')...
So (for the time being) I went about manually reconciling them through a few steps.
First I use my location data and get a list of all the ID's like this:
location_ids = [s['location_id'] for s in location_data]
Then I get the Location objects for those ID's:
location_items = Location.objects.filter(
id__in=location_ids
)
Then I make a small dictionary with the ID and the name:
location_names = [
{'location_id':s.id, 'location_name': s.name}
for s in location_items
]
Then I chain the two lists of dictionaries together and and create a new one from them based on the 'location_id' tying each dictionary together.
additional_location_data = defaultdict(dict)
for d in chain(past_enrollments, location_names):
additional_location_data[d['location_id']].update(d)
This worked to reconcile the location_id with the name of the Location object and put the name in a dictionary (inside of a list) in the appropriate spots.
It's probably fairly 'ugly' for now - but I'll worry about cleaning it up later.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.