Tuesday, February 21, 2017

Re: Flattening model relationships (in APIs)

Ankush

I think you might have to provide more than one method for retrieving an
address so applications can request particular subsets. Perhaps a
local-postal address, international-postal address, geo-location,
what-three-words address and of course the full bucket as required.

I think it is always best to normalize as much as possible in the
beginning and de-normalize only if performance becomes an issue.

Also ...

https://hackernoon.com/10-things-i-learned-making-the-fastest-site-in-the-world-18a0e1cdf4a7#.3l8n34dvk

Mike

On 22/02/2017 6:09 AM, Ankush Thakur wrote:
> I'm using DRF for an API. My problem is that I defined my postal
> address like this (breaking it up into City, State, Country):
>
> class Country(models.Model):
> class Meta:
> db_table = 'countries'
>
> name = models.TextField()
> code = models.TextField(unique=True)
>
> class State(models.Model):
> class Meta:
> db_table = 'states'
>
> name = models.TextField()
> code = models.TextField(unique=True)
> country = models.ForeignKey('Country', on_delete=models.CASCADE)
>
>
> class City(models.Model):
> class Meta:
> db_table = 'cities'
>
> name = models.TextField()
> code = models.TextField(unique=True)
> state = models.ForeignKey('State', on_delete=models.CASCADE)
>
> class Address(models.Model):
> class Meta:
> db_table = 'addresses'
> building_no = models.TextField()
> street = models.TextField(null=True)
> locality = models.TextField(null=True)
> landmark = models.TextField(null=True)
> pincode = models.TextField(null=True)
> latitude = models.DecimalField(max_digits=9, decimal_places=6,
> null=True)
> longitude = models.DecimalField(max_digits=9, decimal_places=6,
> null=True)
> city = models.ForeignKey('City', on_delete=models.CASCADE)
>
> Now, in my system, a venue has an address, and so the serializes are
> defined like this:
>
> class VenueSerializer(serializers.ModelSerializer):
> address = AddressSerializer()
> offerings = OfferingSerializer(many=True)
>
> class Meta:
> model = Venue
> fields = ['id', 'name', 'price_per_day', 'status',
> 'offerings', 'address', 'photos']
>
> which leads us to:
>
> class AddressSerializer(serializers.ModelSerializer):
> city = CitySerializer()
>
> class Meta:
> model = Address
> fields = ['id', 'building_no', 'street', 'locality',
> 'landmark', 'pincode', 'latitude', 'longitude', 'city']
>
> which leads us to:
>
> class CitySerializer(serializers.ModelSerializer):
> state = StateSerializer()
>
> class Meta:
> model = City
> fields = ['id', 'name', 'code', 'state']
>
> which leads us to:
>
> class StateSerializer(serializers.ModelSerializer):
> country = CountrySerializer()
>
> class Meta:
> model = State
> fields = ['id', 'name', 'code', 'country']
>
> which finally leads to:
>
> class CountrySerializer(serializers.ModelSerializer):
> class Meta:
> model = Country
> fields = ['id', 'name', 'code']
>
> and when this gets serialized, the address is given in the following
> format:
>
> "address": {
> "id": 2,
> "building_no": "11",
> "street": "Another Street",
> "locality": "",
> "landmark": "Fortis Hospital",
> "pincode": "201003",
> "latitude": "28.632778",
> "longitude": "77.219722",
> "city": {
> "id": 1,
> "name": "Delhi",
> "code": "DEL",
> "state": {
> "id": 1,
> "name": "Delhi",
> "code": "DEL",
> "country": {
> "id": 1,
> "name": "India",
> "code": "IN"
> }
> }
> }
> }
>
> So there's a hell lot of nesting from city to state to country. If the
> relationship chain was even deeper, there would be even more nesting,
> which I feel isn't great for API consumers. What is the best practice
> here to put state and country at the same level as the city? I think
> this will also complicate the logic while POSTing data, so I'm
> interested in knowing about that as well.
>
> I'm sorry if there is too much code, but I couldn't think of a better
> way to convey the situation than actually post everything.
>
>
> Regards,
> Ankush Thakur
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users+unsubscribe@googlegroups.com
> <mailto:django-users+unsubscribe@googlegroups.com>.
> To post to this group, send email to django-users@googlegroups.com
> <mailto:django-users@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/CALX%3DrK%2Bgbbro%2BkFYsq%3DFDCSu2kw6KRmsfKRamKLA%2Bisrgj%3DboQ%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CALX%3DrK%2Bgbbro%2BkFYsq%3DFDCSu2kw6KRmsfKRamKLA%2Bisrgj%3DboQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/afb3578e-727e-3416-5e1f-cc4fb0d372bb%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment