W Almeida
W Almeida

Reputation: 27

How make a get request with an ForeignKey atribute in Django?

Basically i want to make a get method that when filled with person_id, list all the addresses of that person in json format. Already tried many other methods but none came close

models.py

from django.db import models
from django.core.validators import RegexValidator

# Create your models here.

class Address(models.Model):
    zipcode = models.CharField(max_length=8)
    state = models.CharField(max_length=100)
    city = models.CharField(max_length=100)
    street = models.CharField(max_length=100)
    number = models.IntegerField()
    person_id = models.ForeignKey('Person', on_delete=models.CASCADE, related_name="addresses")

class Person(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()

urls.py

from django.contrib import admin
from django.conf.urls import include,url
from data.views import PersonViewSet, AddressViewSet
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'person', PersonViewSet, base_name='person')
router.register(r'address', AddressViewSet, base_name = 'address')

urlpatterns = [
    url(r'^', include(router.urls)),
]

Example: url: http://localhost:8000/address
method: GET
param: person_id: 0001

This request expect a list like that
{
"id": 5,
"zipcode": "111",
"state": "FL",
"city": "Miami",
"street": "12",
"number": 111,
"person_id": 1
}

Upvotes: 0

Views: 62

Answers (2)

zaidfazil
zaidfazil

Reputation: 9235

You could write a custom manager for filtering using GET parameters.

As an example,

class AddressQuerySet(models.QuerySet):

    def filter_by_request_params(self, request):

        person_str = request.GET.get('person', None)

        if person_str:
            self = self.filter(person_id=int(person_str.strip()))

        return self

In your models,

class Address(models.Model):
    ......
    ......

    objects = AddressQuerySet.as_manager()

In your viewsets,

class AddressViewSet(viewsets.ModelViewSet):
    ......

    def list(self, request, *args, **kwargs):
        self.queryset = self.queryset.filter_by_request_params(request)
        return super(AddressViewSet, self).list(request, *args, **kwargs)

Now you can add more filters in the QuerySet() method and use it as GET parameters, like http://127.0.0.1:8000/address/?person=1

Upvotes: 0

user8060120
user8060120

Reputation:

you can use detail_route

from rest_framework.decorators import detail_route

class PersonViewSet(viewsets.ModelViewSet):
# You code here

    @detail_route(methods=['get'], )
    def addresses(self, request, pk):
        """
        Show person address.
        """
        person = self.get_object()
        serializer = AddressSerializer(person.addresses, many=True)
        return Response(serializer.data)

now you can get list of the person addresses by http://localhost:8000/person/1/addresses

Upvotes: 1

Related Questions