I want to serialize a QuerySet into a JSON object instead of JSON array.
For model Day, the serialized QuerySet should be an object with Day.date keys and serialized Days as values.
class DaySerializer(serializers.ModelSerializer):
class Meta:
model = Day
exclude = []
This returns an array of serialized objects:
DaySerializer(Day.objects.all(),many=True).data
{'15.02.2005':{...},
'16.02.2005':{...},
...
}
I'm curious if there is some DRF way to do that.
AFAIK there is not an out-of-the-box way of doing that, but you can override .to_representation() and .to_internal_value() methods of the serializer to achieve that.
These methods enable you to alter how both serialization and de-serialization is done.
See here for details.
Related
I am wondering if it is possible to store a tuple in a attribute instance in Django?
Something like:
class MyModel(models.Model):
my_tuple_field = TupleField()
and then create an instance of MyModel as follow:
an_instance = MyModel.objects.create(my_tuple_field=('foo', 'bar'))
Thanks,
As #p14z suggests, the best way to save my tuple was the ArrayField. For my example, I just wanted to save a Polygon extent, with this format:
(3.7739613717694787, 50.31527681737183, 4.726162032377, 50.49743217278623)
from django.contrib.postgres.fields import ArrayField
my_tuple_field = ArrayField(models.FloatField(), size=4, null=True)
You can use JSONField if you are using PostgreSQL, or you can very easily encode a list or tuple as a JSON list and store it in a CharField:
obj.foo_list = json.dumps( (2,3,4)) # "[2, 3, 4]"
obj.save()
obj = Foo.objects.get( ...)
foo_tuple = tuple( json.loads( obj.foo_list))
You can encapsulate this behaviour in a model property (with getter and setter), or you can build it in to model instance creation and save.
The main difference between JSONField and CharField containing JSON, is to what extent you can filter a queryset based on the contents of the field. PostgreSQL JSONfield allows much greater precision.
In our project we are using ResourceRelatedField for a foreign key field in one of our serializers to comply with JSON:API format. This is how it looks:
types = ResourceRelatedField(
queryset=Type.objects,
many=True
)
The problem that I have is that I want to exclude some of the items from the queryset of this field so that I don't get all the items from the Type model, but a subset.
If I write something like this it doesn't work:
types = ResourceRelatedField(
queryset=Type.objects.exclude(id=13),
many=True
)
Didn't find anything related in the documentation.
Perhaps You can use a SerializerMethodResourceRelatedField? (not tested).
types = SerializerMethodResourceRelatedField(many=True)
def get_types(self, obj):
return Type.objects.exclude(id=13)
I have a Model with a JSON Field.
data = JSONField(default=dict)
Is there an efficient way - or queryset filter - to find all instances of this Model that do not have a speicfic key in the json field.
Django documentation includes has_key function for JSON field.
Essentially i'm looking for a way to do not_has_key
My current method:
queryset = MyObj.objects.all()
for obj in queryset:
if 'my_key' not in obj.data:
do_work()
else:
pass
#key_already_exists
Many thanks
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' )
)
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.
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' )
I'm creating an API and I need to return data in a dictionnary format sothat it can be serialized (by the API mechanism).
The code that currently works is something as simple as:
def mymethod(self):
queryset1 = MyClass.objects.get(...) # Ccontains 1 object, easy to deal with
queryset2 = OtherClass.objects.filter(...) # Contains N objects, hard to deal with !
return {
'qs1_result': queryset1.some_attribute # This works well
}
Returning data from queryset1 is easy because there is 1 object. I just pick the attribute I need and it works. Now let's say that in addition, I want to return data from queryset2, where there are many objects, and that I don't need every attributes of the object.
How would you do that?
I repeat that I do NOT need to make the serialization myself. I just need to return structured data sothat the serialization can be made.
Thanks a lot.
From the Django docs: https://docs.djangoproject.com/en/dev/topics/serialization/#subset-of-fields
Subset of fields
If you only want a subset of fields to be serialized, you can specify a fields argument to the serializer:
from django.core import serializers
data = serializers.serialize('json', SomeModel.objects.all(), fields=('name','size'))
In this example, only the name and size attributes of each model will be serialized.