Serialize model with foreign key Django - json

I have the following json:
The problem with it is the 'tipo_envase' field, whose id is being returned in my json, but I do not want the id, but the whole object that is linked to tipo_envase, which is basically this json:
I tried to serialize the models this way
class TipoEnvaseSerializer(serializers.ModelSerializer):
class Meta:
model = Tipoenvase
fields = ('id','nombre')
class PresentationSerializer(serializers.ModelSerializer):
class Meta:
model = Presentation
fields = ('nombre','capacidad','tipo_envase')
And the models are these:
class Presentation(models.Model):
nombre = models.CharField(max_length=100)
capacidad = models.CharField(max_length=100)
tipo_envase = models.ForeignKey('Tipoenvase', on_delete=models.CASCADE)
def __str__(self):
return self.nombre + " " + self.capacidad + " " + self.tipo_envase.nombre
class Tipoenvase(models.Model):
nombre = models.CharField(max_length=100)
def __str__(self):
return self.nombre
In summary the following json structure is required:
`{
"nombre":"Frasco"
"capacidad":"410 gr"
"tipo_envase":{
"id":"1"
"nombre":"vidrio"
}
}`

You can nest the serializers:
class PresentationSerializer(serializers.ModelSerializer):
tipo_envase = TipoEnvaseSerializer()
class Meta:
model = Presentation
fields = ('nombre','capacidad','tipo_envase')

Related

Return nested JSON from Models with relations in Django

models.py (simplified)
class Author(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
def get_books(self):
return Book.objects.filter(author=self.pk)
class Book(models.Model):
name = models.CharField(max_length=255)
pages = models.IntegerField()
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return f'{self.name} from {self.author}'
class Paragraph(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
def __str__(self):
return f'{self.name} from {self.book}'
I want to return all the instances in a json file with this structure:
[
{
"name": 'Dumas',
"books": {
"name": "The count of Montecristo",
"paragraphs": {
"name": "paragraph_name_1",
},
{
"name": "paragraph_name_2",
},
{
"name": "The three Musketeers",
"paragraphs": {
"name": "paragraph_name",
},
]
What I tried:
serializers.py
class AuthorSerializer(serializers.ModelSerializer):
books = serializers.CharField(source='get_books', read_only=True)
class Meta:
model = Author
fields = ['name', 'books']
This add the books key but the value is the string representation of the istances of Book (of course), how I make the value being the serialized istances of Book? I have created a BookSerializer.
Notes:
I know that I can created a nested json by creating a serializer for Paragraph with depth = 2 but this will include fields I don't want (like pages in Book) and the json structure will be totally different.
You can create nested serializer as
class ParagraphSerializer(serializers.ModelSerializer):
class Meta:
model = Paragraph
fields = ("name",)
class BookSerializer(serializers.ModelSerializer):
paragraphs = ParagraphSerializer(source="paragraph_set", many=True, read_only=True)
class Meta:
model = Book
fields = ("name", "paragraphs")
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(source="book_set", read_only=True, many=True)
class Meta:
model = Author
fields = ['name', 'books']

How to create object with Foreign Key

Fisrt,here is my models:
class Question(models.Model):
description = models.CharField(max_length=200)
analysis = models.CharField(max_length=50)
def __str__(self):
return self.description
class QuestionOption(models.Model):
question = models.ForeignKey(Question,related_name='options')
content = models.CharField(max_length=100)
isAnswer = models.BooleanField()
def __str__(self):
return self.question.description + " " + self.content
My Serializers:
class QuestionSerializer(ModelSerializer):
class Meta:
model = Question
fields = '__all__'
The Serializer of QuestionOption is as same
My ViewSet:
class QuestionViewSet(ModelViewSet):
queryset = Question.objects.all()
serializer_class = QuestionRetriveSerilzer
I want to post a Json data,like this:
{
"options": [
{
"content": "This is the first option",
"isAnswer": false
},
{
"content": "This is the second option",
"isAnswer": true
}
],
"description": "which one is true?",
"analysis": "It's esay"
}
I hope my QuestionViewSet can create a Question and two QuestionOption for me automatically,and when I post that Json data,the options is null list,so I override the create method of QuestionViewSet,like this:
def create(self, request, *args, **kwargs):
serializer = QuestionSerializer(data=request.data)
question = serializer.save()
for data in request.data['options']:
data['question'] = question.id
optionSeializer = OptionSerializer(data=data)
print optionSeializer.is_valid()
optionSeializer.save()
return Response(serializer.data,status=status.HTTP_200_OK)
And this method can work,but I want to find a simpler way to do it,cause I must override update and other methods,it's not a easy task...
So how to design Serializers and ViewSet in order to automatically create objects and update objects with foreign key ?
drf-writable-nested may help .

Django serializer is not returning JSON data

I have a model Domain:
class Domain(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
And a corresponding serializer:
class DomainSerializer(serializers.ModelSerializer):
class Meta:
model = Domain
fields = ('name',)
I'm trying to serialize a queryset in a view like this:
def getDomains(request):
domains = Domain.objects.filter(name__startswith=request.GET['name_startsWith'])
data = DomainSerializer(domains, many=True)
print(data.data)
return HttpResponse(data.data)
This is not working correctly, and data.data is :
[OrderedDict([('name', 'Math')])]
I would like to have a JSON object, something like:
{'name': 'Math'}.
Try using JsonResponse to return the data:
from django.http import JsonResponse
.....
return JsonResponse(data.data)

Django AttributeError 'float' object has no attribute 'split'

I installed the module Django Import / Export link
the installation went smoothly. Now when I want to import a file with the extension .xls it shows me the following error:
AttributeError at /admin/xxxx/xxxx/process_import/
'float' Has No object attribute 'split'
Exception Location:
C:\Python34\lib\site-packages\import_export\widgets.py in clean, line 321
When I edit the file here widgets.py source code
def clean(self, value):
if not value:
return self.model.objects.none()
if isinstance(value, float):
ids = [int(value)]
else:
ids = value.split(self.separator)
ids = filter(None, value.split(self.separator))
return self.model.objects.filter(**{
'%s__in' % self.field: ids
})
Here are the lines 321 ids = filter(None, value.split(self.separator))
Django models
class Vehicule(models.Model):
matricule = models.CharField(max_length=200)
modele = models.CharField(max_length=200)
annee = models.IntegerField()
def __str__(self):
return self.matricule
class Ligne(models.Model):
nom = models.CharField(max_length=200)
vehicule = models.ManyToManyField(Vehicule, through='Affecter_Vehicule_Ligne')
def __str__(self):
return str(self.nom)
class Affecter_Vehicule_Ligne(models.Model):
vehicule = models.ForeignKey(Vehicule, on_delete=models.CASCADE)
ligne = models.ForeignKey(Ligne, on_delete=models.CASCADE)
actif = models.BooleanField(default=False)
dateAffectation = models.DateTimeField(null=True)
def __str__(self):
return str(self.dateAffectation)
class Arret(models.Model):
nom = models.CharField(max_length=200, null=True)
latitude = models.CharField(max_length=200, null=True)
longitude = models.CharField(max_length=200, null=True)
lignes = models.ManyToManyField(Ligne, through='Ligne_Arret')
def __str__(self):
return str(self.nom)
class Ligne_Arret(models.Model):
sens = models.CharField(max_length=200)
section = models.BooleanField(default=False)
ligne = models.ForeignKey(Ligne, on_delete=models.CASCADE)
arret = models.ForeignKey(Arret, on_delete=models.CASCADE)
def __str__(self):
return str(self.arret)
Django admin
class VehiculeAdmin(admin.ModelAdmin):
list_display = ('matricule', 'modele', 'annee')
search_fields = ('matricule', 'modele')
class Affecter_Vehicule_LigneAdmin(admin.ModelAdmin):
list_display = ('vehicule', 'dateAffectation', 'ligne')
class ArretAdmin(ImportExportModelAdmin):
pass
class Ligne_ArretAdmin(admin.ModelAdmin):
list_display = ('ligne', 'arret', 'section', 'sens')
admin.site.register(Vehicule, VehiculeAdmin)
admin.site.register(Ligne)
admin.site.register(Affecter_Vehicule_Ligne, Affecter_Vehicule_LigneAdmin)
admin.site.register(Arret, ArretAdmin)
admin.site.register(Ligne_Arret, Ligne_ArretAdmin)
Help me please to solve this problem ???
You are trying to split a float value in this line ids = filter(None, value.split(self.separator))
I think you can just remove this line. As you handle the None case and split before.

In Django Rest Framework, how do I serialize values to an arraylist?

In Django Rest Framework 3.0+,I want get this value:
{
image:[img1,img2,img3]
}
and my code like:
models.py
class UserDynamic(models.Model):
"""User dynamic"""
user = models.ForeignKey(settings.AUTH_USER_MODEL)
content = models.TextField(max_length=200)
createtime = models.DateTimeField(auto_now_add=True)
class UserDynamicImage(models.Model):
"""User dynamic images"""
userdynamic = models.ForeignKey(UserDynamic)
image = models.ImageField(upload_to='UserDynamicImage/')
serializers.py
class UserDynamicImageSerializer(serializers.ModelSerializer):
def to_representation(self, obj):
return obj.image
class UserDynamicSerializer(serializers.ModelSerializer):
user = UserProfileSerializer()
imgs = serializers.SerializerMethodField('GetImage')
# imgs = serializers.ListField(img = serializers.ImageField())
# imgs = UserDynamicImageSerializer(many=True, read_only=True)
class Meta:
model = UserDynamic
fields = ('id', 'user', 'content', 'imgs', 'createtime')
def GetImage(self,UserDynamic):
entity = UserDynamicImage.objects.filter(userdynamic = UserDynamic)
return UserDynamicImageSerializer(entity,many=True,context={"request": self.context['request']}).data
Right now,it return a error:
is not JSON serializable
In your UserDynamicImageSerializer instead of returning obj.image return obj.image.url
you can do like:
class UserDynamicImageSerializer(serializers.ModelSerializer):
def to_representation(self, obj):
if obj.image:
return obj.image.url
Another way to do this without using UserDynamicImageSerializer:
class UserDynamicSerializer(serializers.ModelSerializer):
user = UserProfileSerializer()
imgs = serializers.SerializerMethodField('GetImage')
class Meta:
model = UserDynamic
fields = ('id', 'user', 'content', 'imgs', 'createtime')
def GetImage(self,UserDynamic):
entity = UserDynamicImage.objects.filter(userdynamic=UserDynamic).values_list('image',flat=True)
return entity