2017-12-10 4 views
1

객체의 다른 세트를 검색하는 경우는 다음과 같습니다장고 URL은 내가 모델 책이

class Book(models.Model): 
    book_id = models.AutoField(primary_key=True) 
    title = models.CharField(max_length=30) 
    # A book can have multiple authors and an author can have multiple books 
    author = models.ManyToManyField('Author') 
    genre = models.CharField(max_length=20) 
    isbn = models.CharField(max_length=20) 
    summery = models.CharField(max_length=100, null=True) 
    language = models.CharField(max_length=20, null=True) 
    status = models.CharField(max_length=15, null=True) 
    number_of_pages = models.IntegerField(blank=True) 
    borrowed = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True) 
    loan_period = models.IntegerField(default=14) 
    due_date = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True) 
    # A library has many books 
    which_library = models.ForeignKey('Library', related_name='books', on_delete=models.CASCADE) 

    #This helps to print in admin interface 
    def __str__(self): 
     return u"%s" % (self.title) 

을 I가 나에게 특정 라이브러리에있는 모든 책을 제공 한 URL :

urlpatterns = [ 
    url(r'^books/(?P<library_id>[0-9]+)$', book_list), 
] 
을 그 책의 객체를 반환

내보기 :

@api_view(['GET', 'POST']) 
def book_list(request, library_id): 
    """ 
    List all books in a specific library, or create a new book for a specific library 
    """ 
    if request.method == 'GET': 
     books = Book.objects.filter(which_library=library_id) 
     print(books) 
     serializer = BookSerializer(books, many=True) 
     return Response(serializer.data) 

내 질문은 : 수 있습니까 그래 어떻게 생 있도록 내 URL과 뷰를 수정할 수 있습니다 경우 도서의 전체 목록을 다른 검색어 매개 변수로 필터링하여 특정 도서를 반환 할 수 있습니다. 즉, api/books/1?genre=Fiction&status=Available과 같은 URL을 클릭하면이 기준을 충족하는 도서를 더 필터링해야합니까? 그렇게하는 것이 좋습니다. 또는이 목적을 위해 별도의 URL과 의견을 쓰는 것이 좋습니다?

답변

1

GET 쿼리에서 쿼리 URL을 가져온 다음 필터를 적용 할 수 있습니다.

URL 쿼리 매개 변수에 전달 된 값은 개체의 GET 특성을 사용하여 장고에서 액세스 할 수 있습니다.

코드는 다음과 같이 보일 것이다 : 필터 그냥 실제로 데이터베이스에 발사하지 않고 쿼리를 기반으로하기 때문에

@api_view(['GET', 'POST']) 
def book_list(request, library_id): 
    """ 
    List all books in a specific library, or create a new book for a specific library 
    """ 
    if request.method == 'GET': 
     genre_query = request.GET.get('genre', None) 
     status_query = request.GET.get('status', None) 

     books = Book.objects.filter(which_library=library_id) 
     if genre_query: 
      books = books.filter(genre=genre_query) 
     if status_query: 
      books = books.filter(status=status_query) 

     print(books) 
     serializer = BookSerializer(books, many=True) 
     return Response(serializer.data) 

이 작동합니다. 따라서 실제 가져 오기 명령이 호출되기 전에 필터를 연결할 수 있습니다 (예 : print 또는 .all()).

이렇게하는 것이 좋으며,이 목적으로 별도의 URL과 의견을 쓰는 것이 좋습니다?

사용 사례에 따라 다르지만, 쿼리 매개 변수를 사용하는 필터는 필터링하는 동안 사용자 지정을 추가하는 매우 일반적인 방법입니다.

+1

Perfect! 답장을 보내 주셔서 감사 드리며 의심의 여지를 없애십시오! 정말 많은 도움이되었습니다 :) – Nitish

+0

도와 드리겠습니다! 당신은 환영합니다 :) – oxalorg

1

뷰 핸들러에 선택적 속성을 전달하려면 검색어와 마찬가지로 액세스 할 수있는 'request.GET which is a QueryDict'에서 액세스 할 수있는 쿼리 매개 변수를 사용할 수 있습니다. 각 필터에 book

if request.method == 'GET': 
    books = Book.objects.filter(which_library = library_id) 
    genre = request.GET.get('genre', None) 
    status = request.GET.get('status', None) 

    if genre: 
     books = books.filter(genre = genre) 
    if status: 
     books = books.filter(status = status) 

    ....  

참고 재 할당 :

귀하의 예를 다시 쓰기. 이는 필터 또는 다른 쿼리 집합 연산이 새 쿼리 집합을 반환하고 기존 쿼리 집합을 변경하지 않기 때문입니다.

+0

당신의 답변을 주셔서 감사합니다! – Nitish