Django - Serialize parents associations - python

I am trying to create a serialized RESTful response from a One to N relationship.
I have a table Lexicon, primary key lexicon_id, I have another table lexicon_attributes, primary key lexicon_attribute_id, foreign key lexicon_id
class Lexicons(models.Model):
"""
Holds all words
"""
lexicon_id = models.BigIntegerField(primary_key=True)
word = models.TextField(blank=True, null=True)
date_created = models.DateTimeField(blank=True, null=True)
date_modified = models.DateTimeField(blank=True, null=True)
class Meta:
managed = True
db_table = 'lexicons'
class LexiconAttributes(models.Model):
class Meta:
managed = True
db_table = 'lexicon_attributes'
lexicon_attribute_id = models.AutoField(primary_key=True)
lexicon_id = models.ForeignKey('Lexicons', db_column='lexicon_id', related_name="lexicon_attributes")
is_verb = models.CharField(max_length=1, blank=True, null=True)
is_plural = models.CharField(max_length=1, blank=True, null=True)
is_past_tense = models.CharField(max_length=1, blank=True, null=True)
serializer
class LexiconAttributesSerializer(serializers.ModelSerializer):
class Meta:
model = LexiconAttributes
fields = '__all__'
class LexiconsSerializer(serializers.ModelSerializer):
lexicon_attributes = LexiconAttributesSerializer(source='*', many=False)
class Meta:
model = Lexicons
When I make a request for /lexicons/2/
{
"lexicon_id": 2,
"lexicon_attributes": {
"lexicon_id": 2
},
"word": "computer",
"date_created": "2015-07-30T20:29:19Z",
"date_modified": "2015-07-30T20:29:19Z"
}
How do I get the other fields in lexicon_attributes table
FYI I am week two into Django, my app was originally done in Cakephp3

class LexiconsSerializer(serializers.ModelSerializer):
lexicon_attributes = LexiconAttributesSerializer()
class Meta:
model = Lexicons
fields = '__all__'
fixed the problem for me after 3 days

Related

DRF: How can I show all fields of a m2m field instead of just the name

I'm building a simple Lead Generator using Django Rest Framework.
I'm trying to show a list of "assigned facilities" inside a lead using django's many to many fields. But all it will show inside the API is the id of each of the facilities associated to the many to many field. How do I access more than just the name using DRF? I basically need to show the name, a description and a picture of the facility from each facility record.
serializers.py
class LeadUpdateSerializer(serializers.ModelSerializer):
is_owner = serializers.SerializerMethodField()
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"PrimaryAddress",
"assigned_facilities",
)
read_only_fields = ("id", "is_owner")
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user
models.py
class Facility(models.Model):
UUID = models.CharField(max_length=150, null=True, blank=True)
Name = models.CharField(max_length=150, null=True, blank=False)
mainimage = models.ImageField(null=True, blank=True)
FacilityDescription = models.TextField(max_length=1000, null=True, blank=True)
def __str__(self):
return self.Name
class Lead(models.Model):
assigned_facilities = models.ManyToManyField(Facility, related_name='assigned_facilities')
created_at = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=40, null=True, blank=True)
last_name = models.CharField(max_length=40, null=True, blank=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
We can like below:
class FacilitySerializer(serializers.ModelSerializer)
class Meta:
fields = (
"id",
"Name",
"mainimage",
"FacilityDescription",
)
class LeadUpdateSerializer(serializers.ModelSerializer):
assigned_facilities = FacilitySerializer(many=True)
is_owner = serializers.SerializerMethodField()
class Meta:
model = Lead
fields = (
"id",
"first_name",
"last_name",
"PrimaryAddress",
"assigned_facilities",
)
read_only_fields = ("id", "is_owner")
def get_is_owner(self, obj):
user = self.context["request"].user
return obj.agent == user

DRF display nested JSON

I have my DRF app. In my case, one wallet can have many entries such as income or expense. When I call my endpoint (viewset) I get data in this format:
[
{
"id": "d458196e-49f1-42db-8bc2-ee1dba438953",
"owner": 1,
"viewable": [],
"entry": []
}
]
How can I get the content of "entry" variable?.
class Category(models.Model):
name = models.CharField(max_length=20, unique=True)
def __str__(self):
return self.name
class BudgetEntry(models.Model):
STATE= [
('income','income'),
('expenses','expenses'),
]
amount = models.IntegerField()
entry_type = models.CharField(max_length=15, choices=STATE, null=True)
entry_category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.SET_NULL)
class WalletInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owner', on_delete=models.CASCADE)
viewable = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='can_view', blank=True)
entry = models.ManyToManyField(BudgetEntry, related_name='BudgetEntry', blank=True)
Serializers.py:
class BudgetEntrySerializer(serializers.ModelSerializer):
class Meta:
model = BudgetEntry
fields = '__all__'
class WalletInstanceSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.id')
class Meta:
model = WalletInstance
fields = '__all__'
Views.py:
class WalletViewset(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = WalletInstanceSerializer
def get_queryset(self):
user_id = self.request.user.id
available = WalletInstance.objects.filter(
Q(owner=user_id)
)
return available
Change your serializer like this:
class WalletInstanceSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.id')
entry = BudgetEntrySerializer(many=True, read_only=True)
class Meta:
model = WalletInstance
fields = '__all__'

composite key not displaying orrecyl on django admin

I have an intermediary model betwen "estados" e "listaflor", the flora2estado uses a composite key- and a primary key to trick django not to throw errors at me-.
When i click in one object at django admin i get this error:
MultipleObjectsReturned at /admin/accounts/flora2estado/99/change/
get() returned more than one Flora2Estado -- it returned 5!
my models.py
class Estados(models.Model):
estado_id = models.AutoField(primary_key=True)
estado_nome = models.CharField(max_length=100, blank=True, null=True)
class Meta:
managed = False
db_table = 'estados'
class Familia(models.Model):
familia_id = models.AutoField(primary_key=True)
familia_nome = models.CharField(max_length=50, blank=True, null=True)
class Meta:
managed = False
db_table = 'familia'
class Flora2Estado(models.Model):
estado = models.OneToOneField(Estados, models.DO_NOTHING, )
especie_id = models.IntegerField()
flora2estado_id = models.AutoField( primary_key=True)
class Meta:
managed = False
db_table = 'flora2estado'
unique_together = (('estado', 'especie_id'),)
admin.py
admin.site.register(Flora2Estado)

How to join multiple Model in Django Rest Framework serializer

In Django, I have the following models.
class Property(models.Model):
address1 = models.CharField(max_length=512)
address2 = models.CharField(max_length=128, blank=True, null=True)
property_type = models.ForeignKey('PropertyType', models.DO_NOTHING, null=True, blank=True, default=None)
geo_info = models.ForeignKey(GeoInfo, models.DO_NOTHING)
class Meta:
indexes = [
models.Index(fields=['address1', ]),
]
db_table = 'property'
class PropertyType(models.Model):
name = models.CharField(max_length=128, blank=True, null=True)
category = models.CharField(max_length=45, blank=True, null=True)
color = models.CharField(max_length=45, blank=True, null=True)
class Meta:
db_table = 'property_type'
indexes = [
models.Index(fields=['name', ]),
]
class GeoInfo(models.Model):
zipcode = models.CharField(max_length=25, blank=True, null=True)
city = models.CharField(max_length=45, blank=True, null=True)
state = models.CharField(max_length=45, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
class Meta:
db_table = 'geo_info'
indexes = [
models.Index(fields=['zipcode', ]),
models.Index(fields=['city', ]),
]
def __str__(self):
return '%s %s' % (self.zipcode, self.city)
I'm trying to use Django REST Framework to serialize PROPERTY model as follows.
class GeoSerializer(serializers.ModelSerializer):
class Meta:
model = GeoInfo
fields = ['zipcode', 'city', 'state']
class PropertyTypeSerializer(serializers.ModelSerializer):
class Meta:
model = PropertyType
class PropertySerializer(serializers.ModelSerializer):
address_geo = GeoSerializer(many=False, read_only=True)
prop_type = PropertyTypeSerializer(many=True, read_only=True)
class Meta:
model = Property
fields = ['id', 'address1', 'address_geo', 'prop_type']
My expected outcome for each item is like
{
"id": 1,
"address1": "test address",
"geo_info":{
"zipcode":"12121",
"city":"12121",
"state":"12121",
},
"property_type": "unknown",
}
and currently, I'm just getting the property data like
{
"id": 1,
"address1": "test address"
}
So can you help me figure out how to serialize these models?
Also, it would be great if you can help me how to flatten the outcome and avoid nested node if possible
your question is not clear fully. You asked for no nesting. This may help you -
class PropertySerializer(serializers.ModelSerializer):
zipcode=serializers.SerializerMethodField()
city=serializers.SerializerMethodField()
state=serializers.SerializerMethodField()
class Meta:
model = Property
fields = ('id','address1','zipcode','city','state','property_type')
def get_zipcode(self,instance):
return instance.geo_info.zipcode
def get_city(self,instance):
return instance.geo_info.city
def get_state(self,instance):
return instance.geo_info.state

How to join models in django serializers?

I'm trying to join two models, but I got the wrong result. How to do it right?
My models:
class MoocherPage(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=False)
name = models.CharField(max_length=48, unique=True, blank=False, null=False)
bio = models.TextField(blank=False, null=False)
class MoocherResource(models.Model):
url = models.URLField(blank=False, null=False)
moocher = models.ForeignKey(MoocherPage, on_delete=models.CASCADE)
And serializers:
class MoocherResourceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
URL_FIELD_NAME = 'url'
model = MoocherResource
fields = ('url', )
class MoocherPageSerializer(serializers.ModelSerializer):
resources = MoocherResourceSerializer(many=True, read_only=True)
class Meta:
model = MoocherPage
fields = ('name', 'bio', 'resources')
depth = 1
I expected
{
"name": "KissofLove",
"bio": "I'm the kiss of love and I collect money for all lovers of the world.",
"resources": ["https://stackoverflow.com/users/KissofLove"]
}
But the resources was not included.
When I change read_only=True to False in the nested serializer an error appears.
AttributeError: Original exception text was: 'MoocherPage' object has no attribute 'resources'.
Your models
class MoocherPage(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=False)
name = models.CharField(max_length=48, unique=True, blank=False, null=False)
bio = models.TextField(blank=False, null=False)
class MoocherResource(models.Model):
url = models.URLField(blank=False, null=False)
moocher = models.ForeignKey(MoocherPage, on_delete=models.CASCADE)
and your serializers,
from rest_framework.serializers import *
class ResourceListingField(RelatedField):
def to_representation(self, value):
return value.url
class MoocherPageSerializer(ModelSerializer):
resources = ResourceListingField(many=True, source='moocherresource_set', read_only=True)
class Meta:
model = MoocherPage
fields = ['name', 'bio', 'resources']
This returns the desired
{
"name": "KissOfLove",
"bio": "I'm the kiss of love and I collect money for all lovers of the world.",
"resources": ["https://stackoverflow.com/users/KissofLove"]
}
response.
Check out Custom relational fields

Categories