## EngEd Community

Section’s Engineering Education (EngEd) Program fosters a community of university students in Computer Science related fields of study to research and share topics that are relevant to engineers in the modern technology landscape. You can find more information and program guidelines in the GitHub repository. If you're currently enrolled in a Computer Science related field of study and are interested in participating in the program, please complete this form .

# Runtime Updation of Multiple Fields using F Function in Django

##### December 30, 2021

In this tutorial, we will learn how we can continuously update multiple fields using the `F` function in Django.

Let us imagine a scenario - a patriot in Nigeria normally has an electricity meter installed in his house. Every second he uses the power, the usage data is sent from the electricity meter to the power office.

Consequently, two values detailing his amount of total power consumed and amount of power remaining are sent to this user via the smart phone.

In this tutorial, we will mimic an electricity meter that reads a user’s power usage on one end, and stream the electricity meter generated data (consumption rate, power remaining, and total power used) on the other end.

This runtime streaming of data can be done easily and efficiently using the Django `F()` function.

### Pre-requisites

To make the most of this tutorial, it is required to have the following:

• Basic understanding of Python.
• Familiarity with the Django framework and Django REST framework.
• Familiarity with the Django browseable API interface.
• PyCharm professional code editor installed.

### How is F() efficient?

The traditional approach would have been to constantly fetch and iterate over the stream of data – readings, get the sum of power used and subtract it from the threshold, to get the values of power used and power remaining. This is a less efficient approach.

With the F(), a single reading object (meant for the user) can be updated on the fly without reference to the previous data, can be saved to the database and be ready for the user to view it. You can do this for multiple fields at a go.

### Implementation

In this demonstration of how F function works, we will simulate a meter reading process as described earlier in this text.

#### Model

We will require three models: `RegisterMeter`, `MeterReading` and `CurrentUsage`. The snippets below show the code for creating these models:

``````from django.db import models

class RegisterMeter(models.Model):
meter_id = models.CharField(max_length=10)

def __str__(self):
return str(self.pk)

meter = models.CharField(max_length=10)
date_sent = models.DateTimeField(auto_now=True)

def __str__(self):
return self.meter

class CurrentUsage(models.Model):
meter = models.CharField(max_length=10)
total_power_used = models.CharField(max_length=10)
power_remaining = models.CharField(max_length=10)

def __str__(self):
return self.meter
``````

#### Serializer

We will also need to have serializers for the models shown in the code snippet above.

The serializers converts objects to JSON format. Serializers for each of the models is shown below:

``````from rest_framework import serializers
from .models import MeterReading, CurrentUsage, RegisterMeter

class Meta:
fields = '__all__'

class CurrentUsageSerializer(serializers.ModelSerializer):
class Meta:
model = CurrentUsage
fields = '__all__'

class RegisterMeterSerializer(serializers.ModelSerializer):
class Meta:
model = RegisterMeter
fields = '__all__'
``````

The `RegisterMeter` in the `models.py` file is used to on-board an electricity meter.

`MeterReading` represents a single data body generated from the electricity meter and sent to the power office.

The `CurrentUsage` is the reading of power used and power remaining.

The idea is that, while onboarding a new electricity meter, a default `CurrentUsage` is created, where the `total_power_used` and `power_remaining` are set to `0` by default.

On every creation of the `MeterReading` object, the `CurrentUsage` object is updated.

#### View

Inside the `views.py` file, we create a view to onboard an electricity meter as shown:

``````class RegisterMeterCreateView(generics.CreateAPIView):
queryset = RegisterMeter.objects.all()
serializer_class = RegisterMeterSerializer

def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid(raise_exception=True):
return Response({"message": "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST)

meter = request.data.get('meter_id')

"meter": meter,
"total_power_used": "0",
"power_remaining": "0",
}

if serializer.is_valid():
serializer.save()

return Response({"message": "Meter has been on-boarded and a default current reading created"},
status=status.HTTP_200_OK)
``````

#### URL

Inside the `urls.py` file, we display the endpoint to access the meter created as shown below:

``````from django.urls import path

from meter.views import RegisterMeterCreateView, check_meter_usage, CreateMeterReading, \
AllMetersListView

urlpatterns = [
path('all-meters', AllMetersListView.as_view()),
]
``````

To view all meters that have been registered, use the code snippet below:

``````class AllMetersListView(generics.ListAPIView):
queryset = RegisterMeter.objects.all()
serializer_class = RegisterMeterSerializer
``````

As a result, we also need to create a view to check for a `CurrentUsage` object using the `meter_id` as shown below:

``````@api_view(['GET'])
def check_meter_usage(self, meter_id):
``````

Similarly, we need an URL with the endpoint to fetch response from the view above:

``````from django.urls import path

from meter.views import RegisterMeterCreateView, check_meter_usage, CreateMeterReading, \
AllMetersListView

urlpatterns = [
path('all-meters', AllMetersListView.as_view()),
path('meter-usage/<str:meter_id>', check_meter_usage), #  New
``````

To create a single meter reading object, we create a new view as shown below:

``````class CreateMeterReading(generics.CreateAPIView):   # New

def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid(raise_exception=True):
return Response({"message": "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST)

meter = request.data.get('meter')

meter_usage_object = CurrentUsage.objects.get(meter=meter)
CurrentUsage.objects.filter(meter=meter_usage_object.meter).update(
)

meter_usage_object.refresh_from_db()

if serializer.is_valid():
serializer.save()
return Response({"message": "Reading created, current usage updated"}, status=status.HTTP_200_OK)
``````

The URL for the view above is:

``````from django.urls import path

from meter.views import RegisterMeterCreateView, check_meter_usage, CreateMeterReading, \
AllMetersListView

urlpatterns = [
path('all-meters', AllMetersListView.as_view()),
path('meter-usage/<str:meter_id>', check_meter_usage),
]
``````

### How the F() works?

Now that we have our models, serializers, views, and URLs ready, let us begin the actual demonstration of the mini-project.

We create a new meter using the endpoint `localhost:8000/add-meter` and fill in the page accordingly:

Creating a new meter

A new meter object created

To check that the meter was successfully registered, visit `localhost:8000/all-meters` to view them:

View all meters

To view details of a particular meter, visit `localhost:8000/meter-usage/PM01` as shown:

View details about a particular meter

Let us create a new `MeterReading` object with value `1` for our meter `PM01` (this reading is sent to the power office) and update the meter’s `CurrentUsage` in the process as shown:

From above, we see that a reading of `1` unit is sent from the meter and consequently, the current usage updated to reflect an expense from the `MeterReading`.

Check the current usage by visiting the endpoint `localhost:8000/meter-usage/PM01` to confirm if the POST operation was successful.

We are assuming a usage threshold of 25 units. So, when the meter read that the user has spent 1 unit, he has 24 left.

Let’s try with a higher meter reading, say `3`:

We see that the `CurrentUsage` is updated again with `total_power_used` as `4` and `power_remaining` as `21`.

MeterReading object updated for meter PM01

After following this tutorial, you may have another insight where one can manipulate the fields of a Django model without having to make too many calls and passing objects about.

The F() does a lot of this heavy-lifting and you can manipulate as many fields as you might want to.

### Points to note

• By using F(), one can keep track of all the changes made. For instance, when `MeterReading` is saved, the power usage history of any user can be fetched, for transparency or audit sakes.
• Validation and conditions can be set before updating any value. For instance, while updating the `CurrentUsage` for every creation of a reading, validations and conditions can be set before.
• The current usage can be reset by sending in a negative number for the `power_used` field, say `-1`.

### Conclusion

In this article, we have learned how to use the F function and why using it is better than the traditional approach

In programming, efficiency matters. It is best that we always seek out ways to improve the efficiency of our programs. In Python, using F function makes our program more efficient.

You can find the full code on Github.

Happy coding!

Peer Review Contributions by: Srishilesh P S