Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework - passing Model data through a function, then posting output in a separate field in the same model

(Django 2.0, Python 3.6, Django Rest Framework 3.8)

I'm trying to fill the calendarydays field in the model below:

Model

class Bookings(models.Model):
    booked_trainer = models.ForeignKey(TrainerProfile, on_delete=models.CASCADE)
    booked_client = models.ForeignKey(ClientProfile, on_delete=models.CASCADE)
    trainer_availability_only = models.ForeignKey(Availability, on_delete=models.CASCADE)
    calendarydays = models.CharField(max_length=300, blank=True, null=True)

    PENDING = 'PENDING'
    CONFIRMED = 'CONFIRMED'
    CANCELED = 'CANCELED'

    STATUS_CHOICES = (
        (PENDING, 'Pending'),
        (CONFIRMED, 'Confirmed'),
        (CANCELED, 'Canceled')
    )


    booked_status = models.CharField(
        max_length = 9,
        choices = STATUS_CHOICES,
        default = 'Pending'
    )

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

Now, I have a function that takes values from trainer_availability_only and converts those values to a list of datetime strings, the returned output would look like this:

{'calendarydays': ['2018-07-23 01:00:00', '2018-07-23 02:00:00', '2018-07-23 03:00:00', '2018-07-30 01:00:00', '2018-07-30 02:00:00', '2018-07-30 03:00:00', '2018-08-06 01:00:00', '2018-08-06 02:00:00', '2018-08-06 03:00:00', '2018-08-13 01:00:00', '2018-08-13 02:00:00', '2018-08-13 03:00:00', '2018-08-20 01:00:00', '2018-08-20 02:00:00', '2018-08-20 03:00:00']}

Problem

How can I fill the calendarydays field with the function output for a user to select from a dropdown, and where should I implement this logic (in my view or the serializer)? My main point of confusion is that, because my function depends on data from trainer_availability_only, I don't want to create a separate model/table for this information (as that would seem too repetitive). I also don't fully understand where in my serializers or views I can implement some sort of dropdown for a User to choose a single calendarydays value for (like I would be able to for a ForeignKey or OneToOneField for example).

Details for the other models aren't really relevant to the question, except trainer_availability_only, which basically gives the user a dropdown selection that would look like this:

('Monday','12:00 am - 1:00 am')
('Wednesday','4:00 pm - 5:00 pm')
etc.

Any help is greatly appreciated.

like image 554
aalberti333 Avatar asked Jul 19 '18 15:07

aalberti333


People also ask

How do you pass extra context data to Serializers in Django REST framework?

In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.

How do you serialize an object in Django REST framework?

Creating and Using Serializers To create a basic serializer one needs to import serializers class from rest_framework and define fields for a serializer just like creating a form or model in Django.

What is difference between Api_view and ViewSet?

APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.

Why do we use Serializers in Django REST framework?

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON , XML or other content types.

What is the use of REST framework in Django?

Django REST Framework is used to create web APIs very easily and efficiently. This is a wrapper around over the Django Framework. There are three stages before creating an API through REST framework, Converting a Model’s data to JSON/XML format (Serialization), Rendering this data to the view, Creating a URL for mapping to the viewset.

What is a model in Django?

A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table. Each model is a Python class that subclasses django.db.models.Model. Each attribute of the model represents a database field.

What is a a field in Django?

A field is thus a fundamental piece in different Django APIs, notably, models and querysets. In models, a field is instantiated as a class attribute and represents a particular table column, see Models. It has attributes such as null and unique, and methods that Django uses to map the field value to database-specific values.

Can I use commoninfo model as a base class in Django?

Instead, when it is used as a base class for other models, its fields will be added to those of the child class. The Student model will have three fields: name, age and home_group. The CommonInfo model cannot be used as a normal Django model, since it is an abstract base class.


1 Answers

Assuming that you will not be using this API through browsable API and some client will consume these API's, you should give a separate endpoint to fetch the options which can be shown in the dropdown.

Since the calendar days only depends on the selected Availability, the endpoint can be something like /availability/<:id>/calender-days, where <:id> is the id of the selected option. This will be a GET request with a separate view where you can call your function which calculates calendar days from Availability object and return the list of calendar days. This endpoint will be useful in both cases when you create a new Booking object or you update that.

On your point of showing in the browsable API form, browsable API forms don't load dynamic fields, so it will not call your logic to fetch calendar days based on the selection. For the Foriegn key and one-to-one relation, it already loads the queryset of the models while rendering the form and uses those to show the dropdowns. But if your actual use case is to consume API's using browsable API form then you will have to write some custom javascript to load the values.

like image 59
Atul Mishra Avatar answered Nov 05 '22 19:11

Atul Mishra