How to operate with two models in one view?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

How to operate with two models in one view?

Anton Smirnov

I have two models: "Sensors" with information about its and "Measurments" .

class Sensor(models.Model):
    date_start = models.DateField()
    Latitude =  models.DecimalField(max_digits=18, decimal_places=15)
    Longitude = models.DecimalField(max_digits=18, decimal_places=15)

    def __str__(self):
        return 'id:%s / %s' % (self.id, self.date_start)

class Measurment(models.Model):
    sens = models.ForeignKey(Sensor, on_delete=models.PROTECT)
    time_of_measurment = models.DateTimeField()
    humidity = models.PositiveSmallIntegerField()
    temperature1 = models.DecimalField(max_digits=5, decimal_places=2)
    temperature2 = models.DecimalField(max_digits=5, decimal_places=2)
    temperature3 = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return 'sens_id:%s, time:%s' % (self.sens.id, self.time_of_measurment)

From each sensor I serially recive measurments. On the page, it is necessary to display the sensor data and the one latest measurement data from the "Measurments" model corresponding for each sensor.

for displaying sensors data I used ListView:

view:

from .models import Sensor, Measurment
class SenorsListView(generic.ListView):
    model = Sensor, Measurment
    context_object_name = 'sensors_list'
    template_name = 'sensors_list.html'
    queryset = Sensor.objects.all().order_by('-date_start')

template "sensors_list.html":

{% extends "base_generic.html" %}
{% block content %}
    <h1>Sensors List</h1>
    {% if sensors_list %}
    <table class="table">
  <tr>
    <td><h4>ID sens<h4></td>
    <td><h4>Date of install<h4></td>
    <td><h4>Latitude<h4></td>
    <td><h4>Longitude<h4></td>
    <td><h4>Data from last measurments<h4></td>
  </tr>
      {% for sensor in sensors_list %}
      <tr>
    <td>{{sensor.id}}</td>
    <td>{{sensor.date_start}}</td>
   <td>{{sensor.Latitude}}</td>
    <td>{{sensor.Longitude}}</td>
    <td>{{}}</td>
      </tr>
      {% endfor %}
    </table>
    {% else %}
      <p>There are no sensors in the DB.</p>
    {% endif %} 
{% endblock %}

But dont know How to display data about last measurments. I think need using aggregate to calculate last_time how Max(time_of_measurment) for each id_sens. And then get it whith filter(sens=id_sens, time_of_measurment = last_time )

How it can be done right?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/75f85eb9-0a7d-45cf-b50d-00add6a8cf51%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to operate with two models in one view?

Daniel Roseman-2
On Tuesday, 15 May 2018 12:21:26 UTC+1, Anton Smirnov wrote:

I have two models: "Sensors" with information about its and "Measurments" .

class Sensor(models.Model):
    date_start = models.DateField()
    Latitude =  models.DecimalField(max_digits=18, decimal_places=15)
    Longitude = models.DecimalField(max_digits=18, decimal_places=15)

    def __str__(self):
        return 'id:%s / %s' % (self.id, self.date_start)

class Measurment(models.Model):
    sens = models.ForeignKey(Sensor, on_delete=models.PROTECT)
    time_of_measurment = models.DateTimeField()
    humidity = models.PositiveSmallIntegerField()
    temperature1 = models.DecimalField(max_digits=5, decimal_places=2)
    temperature2 = models.DecimalField(max_digits=5, decimal_places=2)
    temperature3 = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return 'sens_id:%s, time:%s' % (self.sens.id, self.time_of_measurment)

From each sensor I serially recive measurments. On the page, it is necessary to display the sensor data and the one latest measurement data from the "Measurments" model corresponding for each sensor.

for displaying sensors data I used ListView:

view:

from .models import Sensor, Measurment
class SenorsListView(generic.ListView):
    model = Sensor, Measurment
    context_object_name = 'sensors_list'
    template_name = 'sensors_list.html'
    queryset = Sensor.objects.all().order_by('-date_start')

template "sensors_list.html":

{% extends "base_generic.html" %}
{% block content %}
    <h1>Sensors List</h1>
    {% if sensors_list %}
    <table class="table">
  <tr>
    <td><h4>ID sens<h4></td>
    <td><h4>Date of install<h4></td>
    <td><h4>Latitude<h4></td>
    <td><h4>Longitude<h4></td>
    <td><h4>Data from last measurments<h4></td>
  </tr>
      {% for sensor in sensors_list %}
      <tr>
    <td>{{sensor.id}}</td>
    <td>{{sensor.date_start}}</td>
   <td>{{sensor.Latitude}}</td>
    <td>{{sensor.Longitude}}</td>
    <td>{{}}</td>
      </tr>
      {% endfor %}
    </table>
    {% else %}
      <p>There are no sensors in the DB.</p>
    {% endif %} 
{% endblock %}

But dont know How to display data about last measurments. I think need using aggregate to calculate last_time how Max(time_of_measurment) for each id_sens. And then get it whith filter(sens=id_sens, time_of_measurment = last_time )

How it can be done right?



An easy way to do this would be to define the default ordering for Measurment to be by reverse time; then you can access `sensor.measurment_set.first` directly in the template.

class Measurment:
    ...
    class Meta:
         ordering = ['-time_of_measurment']

...

{% for sensor in sensors_list %}
  ...
  {% with sensor.measurment_set.first as last_measurment %}
    {{ last_measurment.humidity }}  # etc
  {% endwith %}
{% endfor %}

--
DR.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/edabb83a-984e-4039-b2d5-e4f854a310c3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.