I have a one to many relationshiop:
class SessionGPS(models.Model):
start_timestamp = models.IntegerField()
end_timestamp= models.IntegerField()
class GPSData(models.Model):
longitude = models.DecimalField(max_digits=15, decimal_places=13)
lat = models.DecimalField(max_digits=15, decimal_places=13)
session_new = models.ForeignKey(SessionGPS, on_delete=models.CASCADE, related_name="sesion_gps")
Each SessionGPS entry has multiple GPSData entries. A session is composed of a set of GPS coordinates. This set is in the model GPSData.
I need to query SessionGPS based in start and end timestamps:
def date_search(request):
data = request.body.decode("utf-8")
start=int(datetime.datetime.strptime(request.POST['start'], '%Y-%m-%d').timestamp())
end=int(datetime.datetime.strptime(request.POST['end'], '%Y-%m-%d').timestamp())
res = GPSData.objects.filter(session_new_id__start_timestamp__gte=start,session_new_id__end_timestamp__lte=end)
res = serializers.serialize("json", res)
return HttpResponse(res, content_type='application/json')
In this way I get all GPSData between the timestamps but are not classified by session, they are merged.
I need to get the query like this:
session 1 ->> all GPSData of that session 1
session 2 ->> all GPSData of that session 2
So in the template I can render like this:
For GPSData in session 1 do something
For GPSData in session 2 do something
etc.
I tried to return multiple queries to the view but it didn't worked.
Thanks for any help.
CodePudding user response:
I don't think there is a query option to what you want. So, the only way I could think of is to post process the data:
models.py:
class SessionGPS(models.Model):
start_timestamp = models.DateTimeField(auto_now_add=True)
end_timestamp = models.DateTimeField(null=True)
class GPSData(models.Model):
longitude = models.DecimalField(max_digits=15, decimal_places=13)
latitude = models.DecimalField(max_digits=15, decimal_places=13)
session = models.ForeignKey(SessionGPS, on_delete=models.CASCADE, related_name="sesion_gps")
views.py:
def gps_timestamps(request):
if request.method == 'POST':
start = request.POST.get('start_date').split('-')
end = request.POST.get('end_date').split('-')
start_date = datetime.datetime(int(start[0]), int(start[1]), int(start[2]))
end_date = datetime.datetime(int(end[0]), int(end[1]), int(end[2]))
data_rows = GPSData.objects.filter(session__start_timestamp__gte=start_date,session__end_timestamp__lte=end_date)
# Initialize dictionary
# with unique sessions keys inside the queryset
data = {}
for row in data_rows:
if row.session.id not in data:
data[row.session.id] = {
'start_time': row.session.start_timestamp.strftime("%Y-%m-%d"),
'end_time': row.session.end_timestamp.strftime("%Y-%m-%d"),
}
else:
pass
# Populate
for key, value in data.items():
gps_data_list = []
for row in data_rows:
if row.session.id == key:
gps_data_list.append( {'latitude': str(row.latitude), 'longitude': str(row.longitude)} )
data[key].update(data=gps_data_list)
# If you really want JSON
json_object = json.dumps(data, indent = 4)
print(json_object)
context = {
'data': data
}
return render(request, 'gps_timestamp.html', context)
gps_timestamp.html (I used bootstrap 5), two inputs with format yyyy-mm-dd:
<div >
<form action="{% url 'app:urlname' %}" method="post">
{% csrf_token %}
<div >
<label for="start_date">Start Date</label>
<input id="start_date" name="start_date" type="text" placeholder="year-month-day" aria-label="start_date">
</div>
<div >
<label for="end_date">End Date</label>
<input id="end_date" name="end_date" type="text" placeholder="year-month-day" aria-label="end_date">
</div>
<input type="submit" value="OK">
</form>
</div>
<div style="flex-direction: column;">
{% for key, obj in data.items %}
<p>Session ID: {{key}}</p>
<p>Start Time: {{obj.start_time}}</p>
<p>End Time: {{obj.end_time}}</p>
<p>GPS Data:</p>
{% for row in obj.data %}
{{row}}
<br>
{% endfor %}
<p>----------------------------------</p>
{% endfor %}
</div>
JSON output of my test:
{
"2": {
"start_time": "2022-11-25",
"end_time": "2022-11-26",
"data": [
{
"latitude": "70.7762500000000",
"longitude": "12.4800500000000"
},
{
"latitude": "42.7545200000000",
"longitude": "71.1392900000000"
},
{
"latitude": "56.1794700000000",
"longitude": "90.8119600000000"
}
]
},
"3": {
"start_time": "2022-11-27",
"end_time": "2022-11-28",
"data": [
{
"latitude": "10.1099500000000",
"longitude": "-19.2024500000000"
},
{
"latitude": "80.1405100000000",
"longitude": "16.2555700000000"
},
{
"latitude": "-16.1924200000000",
"longitude": "-51.7266300000000"
},
{
"latitude": "19.4745700000000",
"longitude": "10.7191800000000"
}
]
}
}
By the way, I have to mention that I had some problems with your GPSData model, when either latitude or logitude had 3 digits. Like, 123.3123123. It only accepts <100, but I didn't get into this.
Just changed SessionGPS to better access data.