2

I want to add an extra field to a query set in Django.

The field does not exist in the model but I want to add it to the query set.

Basically I want to add an extra field called "upcoming" which should return "True"

I already tried adding a @property method to my model class. This does not work because apparently django queries access the DB directly.

models.py

class upcomingActivity(models.Model):
    title      = models.CharField  (max_length=150)
    address    = models.CharField  (max_length=150)

Views.py

def get(self, request):
    query = upcomingActivity.objects.all()
    feature_collection = serialize('geojson', query ,
                                    geometry_field='location',
                                    fields= ( 'upcoming','title','address','pk' ) 
                                    )

2 Answers2

2

This answer is for the case that you do not want to add a virtual property to the model (the model remains as is).

To add an additional field to the queryset result objects:

from django.db.models import BooleanField, Value

upcomingActivity.objects.annotate(upcoming=Value(True, output_field=BooleanField())).all()

Each object in the resulting queryset will have the attribute upcoming with the boolean value True. (Performance should be nice because this is easy work for the DB, and Django/Python does not need to do much additional work.)

EDIT after comment by Juan Carlos:

The Django serializer is for serializing model objects and thus will not serialize any non-model fields by default (because basically, the serializer in this case is for loading/dumping DB data).

See https://docs.djangoproject.com/en/2.2/topics/serialization/

Django’s serialization framework provides a mechanism for “translating” Django models into other formats.

See also: Django - How can you include annotated results in a serialized QuerySet?


From my own experience:

In most cases, we are using json.dumps for serialization in views and this works like a charm. You can prepare the data very flexibly for whatever needs arize, either by annotations or by processing the data (list comprehension etc.) before dumping it via json.


Another possibility in your situation could be to customize the serializer or the input to the serializer after fetching the data from the DB.

Risadinha
  • 16,058
  • 2
  • 88
  • 91
  • this is the correct answer to the question asked. However I discovered that the serializer will not read the extra field. As @Risadinha suggested a custom serializer would be needed to add a custom field to a django serializer. – Juan Carlos Aug 05 '19 at 09:54
  • @JuanCarlos you are right. I've added this info and a link to another SO question about that problem. – Risadinha Aug 05 '19 at 10:33
1

You can use a class function to return the upcoming value like this:

def upcoming(self):
    is_upcoming = # some logic query or just basically set it to true. 
    return is_upcoming

then call it normally in your serializer the way you did it.

fields= ( 'upcoming','title','address','pk' )
Ramy M. Mousa
  • 5,727
  • 3
  • 34
  • 45