1. 준비물

GeoDjango는 django project의 일종으로 위치 데이터를 다룰 수 있게 해줍니다. 위치 데이터는 보통 구글맵을 이용한 좌표 데이터를 의미한다고 봐도 됩니다. 그 외에도 3d나 2d 좌표를 이용한 계산 등의 기능도 가능케 합니다.

GeoDjango : https://docs.djangoproject.com/en/2.0/ref/contrib/gis/


models.py 에서 설정하는 여러가지 방법이 있지만 PointField를 쓰기로 했습니다. 


class Post(models.Model):
    
    author = models.ForeignKey(User, related_name='related_postwriter')
    text = models.TextField(null = True, blank = True)
    image = models.ImageField(null = True, blank = True, upload_to='gogo')
    created_date = models.DateTimeField(
        default=timezone.now
        )
    point = models.PointField(blank=False, null=False)
    #여기서 PointField를 쓴다. PointField는 좌표를 저장하기에 좋습니다.
 
    def __str__(self):              # __unicode__ on Python 2
        return self.author
cs


이젠 PointField의 정보를 views.py에서 다룰 차례입니다.

그 전에 admin.py에 Post 모델을 등록합니다.


from .models import Post
 
admin.site.register(Post)
cs


2. views.py 설정


그리고 views.py 에서 import는 이렇게 해 줍니다.


from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.measure import D
cs


ViewSet class를 만듭니다.


class PostViewSet(viewsets.ModelViewSet):
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]
    queryset = Post.objects.all()
cs


django-rest-framework 를 쓰고 있으니 import할 것이 있습니다. django-rest-framework를 더욱 편리하게 해줍니다.

django-rest-framework는 django 에서 RESTful API를 구성하기 쉽게 해 줍니다. 많이 사용되는 패키지입니다.

django-rest-framework : http://www.django-rest-framework.org/


from rest_framework import filters, viewsets, generics
 
cs


이러면 viewsets.ModelViewSet을 쓸 수 있습니다.


from blog.models import Post
 
cs

모델을 호출하지 않으면 동작하지 않습니다.


    def get_queryset(self) :
        lat = self.request.GET.get('user_lat''15')
        lon = self.request.GET.get('user_lon''13')
        userpoint = GEOSGeometry('POINT(' + lon + ' ' + lat + ')', srid=4326)
        self.result = []
        return self.result
cs


쿼리셋을 불러오는 일부분입니다. 여기에 옵션을 조금 더 추가합니다.


        while i<20:
            elasped_minutes = datetime.now() - timedelta(minutes=10*i)
            list_i = Post.objects.filter(point__distance_lte = (userpoint, D(m=i*500))).order_by("-created_date")
            if len(self.result) > 50:
                self.result = self.result[:50]
                break
            i += 1
cs



이렇게 되면 일정 거리에 있는 결과들을 결과값으로 가져오게 됩니다. 500m 단위로 필터를 반복하게 구성했습니다.


3. 작성자와 request.user 일치시키기

작성자는 글쓴 사람으로 등록되게 하겠습니다.

serializer의 self값에서 request요소를 받아내고 있음을 이용합니다.


    def perform_create(self, serializer):
        serializer.save(author=self.request.user)
cs


+ Recent posts