Django-filter: FilterSet에 ν•„λ“œκ°€ μ œκ³΅λ˜μ§€ μ•ŠμœΌλ©΄ μ˜ˆμ™Έ λ°œμƒ

에 λ§Œλ“  2016λ…„ 09μ›” 28일  Β·  11μ½”λ©˜νŠΈ  Β·  좜처: carltongibson/django-filter

class BooksFilter(filters.FilterSet):
    class Meta:
        model = Books

ν•„ν„° μ„ΈνŠΈ ν΄λž˜μŠ€μ—μ„œ fields μ˜΅μ…˜μ„ μƒλž΅ν•˜λ©΄(μœ„μ™€ 같이) λͺ¨λ“  λͺ¨λΈ ν•„λ“œκ°€ ν•„ν„° μ„ΈνŠΈμ— ν¬ν•¨λ©λ‹ˆλ‹€. μ΄λŠ” 양식이 탐색 κ°€λŠ₯ν•œ APIμ—μ„œ λ Œλ”λ§λ˜λŠ” DRF와 ν•¨κ»˜ μ‚¬μš©λ  λ•Œ 정보 λˆ„μΆœλ‘œ μ΄μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

Django와 DRF λͺ¨λ‘ 잠재적인 λ³΄μ•ˆ 문제둜 인해 양식/직렬 λ³€ν™˜κΈ°μ— ν•„λ“œλ₯Ό λͺ…μ‹œμ μœΌλ‘œ 지정해야 ν•©λ‹ˆλ‹€. 이것은 django-filter ν•„ν„°μ…‹μ—μ„œλ„ ν•„μš”ν•©λ‹ˆλ‹€.
http://www.django-rest-framework.org/api-guide/serializers/#specifying -what-fields-to-include
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#selecting -the-fields-to-use

PR에 κΈ°μ—¬ν•˜κ±°λ‚˜ ν•„μš”ν•œ 경우 정보 유좜둜 μ΄μ–΄μ§ˆ 수 μžˆλŠ” 상황에 λŒ€ν•΄ μžμ„Ένžˆ μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

ImprovemenFeature

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

btw - 데이터 λˆ„μΆœμ€ #451에 μ˜ν•΄ λΆ€λΆ„μ μœΌλ‘œ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μ§€κΈˆ λ‹Ήμž₯은 μ •μ˜λ˜μ§€ μ•Šμ€/λ³€κ²½λ˜λŠ” λ™μž‘μ— λŒ€ν•œ μ‚¬μš© 쀑단 κ²½κ³  κ°€ ν‘œμ‹œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 1.0μ—μ„œ μƒˆλ‘œμš΄ λ™μž‘μ€ Meta.fields λ˜λŠ” Meta.fields = None κ°€ μ—†μœΌλ©΄ 아무 것도 ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λͺ¨λ“  11 λŒ“κΈ€

@nip3o λ„€. 이것을 λ³΄κ²Œλ˜μ–΄ κΈ°μ©λ‹ˆλ‹€.

λ˜ν•œ DRF에 따라 ν•„λ“œμ— μ„ μ–Έλœ ν•„ν„°κ°€ ν•„μš”ν•˜λ„λ‘ ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

btw - 데이터 λˆ„μΆœμ€ #451에 μ˜ν•΄ λΆ€λΆ„μ μœΌλ‘œ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μ§€κΈˆ λ‹Ήμž₯은 μ •μ˜λ˜μ§€ μ•Šμ€/λ³€κ²½λ˜λŠ” λ™μž‘μ— λŒ€ν•œ μ‚¬μš© 쀑단 κ²½κ³  κ°€ ν‘œμ‹œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 1.0μ—μ„œ μƒˆλ‘œμš΄ λ™μž‘μ€ Meta.fields λ˜λŠ” Meta.fields = None κ°€ μ—†μœΌλ©΄ 아무 것도 ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ˜ν•œ ν•„λ“œμ— DRF에 따라 μ„ μ–Έλœ ν•„ν„°κ°€ ν•„μš”ν•˜λ„λ‘ ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

이것이 Meta.fields 에 λŒ€ν•œ dict ꡬ문과 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. 예:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter()

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            ???
        }

이것이 dict ꡬ문과 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

λ¬Όλ‘ .

λ‚˜λŠ” μ—¬μ „νžˆ 이것에 λŒ€ν•΄ μΌμ’…μ˜ :-1:μž…λ‹ˆλ‹€. Meta.fields dict ꡬ문 w/ μ„ μ–Έλœ ν•„ν„°λ₯Ό ν•΄κ²°ν•˜λŠ” 방법이 μ—†μŠ΅λ‹ˆλ‹€. 적어도 μ–΄μƒ‰ν•˜μ§€ μ•Šμ€ λ°©μ‹μœΌλ‘œ:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter(name='username', lookup_expr='exact')
    username_like = filters.CharFilter(name='username', lookup_expr='icontains')
    relevance = filters.CharFilter(method='filter_relevance')

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            'username': ['exact'],  # match w/ the lookup_expr? 
            'username_like': ['icontains'],
            'relevance': [???]  # What about method filters?
        }

λ˜ν•œ 이 μš”κ΅¬ 사항은 FilterSet.FILTER_DEFAULTS 에 μžˆλŠ” ν•„λ“œ 클래슀λ₯Ό μƒμ†ν•˜μ§€ μ•ŠλŠ” μ‚¬μš©μž 지정 λͺ¨λΈ ν•„λ“œμ— λŒ€ν•œ λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€. μ‚¬μš©μž μ •μ˜ ν•„λ“œμ—λŠ” λ‹€μŒμ΄ ν•„μš”ν•©λ‹ˆλ‹€.

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting
        fields = ['mask']
        filter_overrides = {
            SubnetMaskField: {'filter_class': MaskFilter},
        }

# vs.

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting

μ°Έκ³  사항: 이 λ‚˜μ€‘ μš”μ μ€ μš°λ¦¬κ°€ _κ³ μΉ  수 μžˆλŠ”_ κ²ƒμž…λ‹ˆλ‹€. Django의 λͺ¨λΈ ν˜•μ‹ λŒ€μ‹  DRF의 직렬 λ³€ν™˜κΈ°μ²˜λŸΌ μž‘λ™ν•˜λ„λ‘ μžλ™ 생성을 λ‹€μ‹œ μž‘μ„±ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ–΄λŠ μͺ½μ΄λ“ , λ‚΄ μ£Όμš” κ΄€μ‹¬μ‚¬λŠ” ꡬ문 μΆ©λŒμž…λ‹ˆλ‹€.

μ’‹μ•„μš”. 일단 λ†”λ‘μž.

λ‚˜λŠ” μ›λž˜ μ œμ•ˆμ„ μ’‹μ•„ν•œλ‹€. λ²”μœ„λ₯Ό _ fields κ°€ λͺ©λ‘μΈ 경우..._둜 λ²”μœ„λ₯Ό μ§€μ •ν•˜λŠ” κ²½ν–₯이 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 쑰금 더 생각해야 ν•©λ‹ˆλ‹€.

μ•½κ°„ μ•žλ’€κ°€ λ§žμ§€λ§Œ μ›λž˜ λ¬Έμ œμ— λŒ€ν•΄μ„œλ§Œ λ‹€μ‹œ μ΄μ •ν‘œλ₯Ό μž‘μ„±ν•˜κ² μŠ΅λ‹ˆλ‹€.

fields λ˜λŠ” exclude λ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€. fields = '__all__' λŠ” μ΅œμ†Œκ°’μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€.

(λͺ©λ‘ 일치λ₯Ό κ°•μ œν•˜μ§€ μ•ŠλŠ” 것은 λ‹€μ‹œ λŒμ•„μ˜¬ 수 μžˆλŠ” λ¬Έμ œμž…λ‹ˆλ‹€.)

κ΄€λ ¨ DRF μ½”λ“œλŠ” λ‹€μŒ κ³Ό κ°™μŠ΅λ‹ˆλ‹€.

        assert not (fields is None and exclude is None), (
            "Creating a ModelSerializer without either the 'fields' attribute "
            "or the 'exclude' attribute has been deprecated since 3.3.0, "
            "and is now disallowed. Add an explicit fields = '__all__' to the "
            "{serializer_class} serializer.".format(
                serializer_class=self.__class__.__name__
            ),
        )

filters_for_model 에 λΉ„μŠ·ν•œ μΆ”κ°€ κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

    # Setting exclude with no fields implies all other fields.
    if exclude is not None and fields is None:
        fields = ALL_FIELDS

μ‹œμž‘ν•˜λ €λ©΄ 더 이상 μ‚¬μš©λ˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€.

fields λ˜λŠ” exclude λ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€. fields = '__all__' λŠ” μ΅œμ†Œκ°’μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€.

λ‚˜λŠ” ν™•μ‹€νžˆ κ·Έ 뒀에 갈 수 μžˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬ PR μž‘μ—…μ„ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λ©‹μžˆλŠ”.

감가 상각에 λŒ€ν•΄ κ±±μ •ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. μ£Όμš” 버전 변경에 λŒ€ν•œ μž‘μ€ λ³€κ²½μž…λ‹ˆλ‹€. λ³€κ²½ λ…ΈνŠΈμ— λͺ…μ‹œν•΄ λ‘μ‹­μ‹œμ˜€. πŸ‘πŸ½

감가 상각에 λŒ€ν•΄ κ±±μ •ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. μ£Όμš” 버전 변경에 λŒ€ν•œ μž‘μ€ λ³€κ²½μž…λ‹ˆλ‹€. λ³€κ²½ λ…ΈνŠΈμ— λͺ…μ‹œν•΄ λ‘μ‹­μ‹œμ˜€.

μ˜λ„λŠ” μ•½κ°„ λ‹€λ₯΄μ§€λ§Œ μ‹€μ œλ‘œ μ—¬κΈ° μ—μ„œ λ‹€λ£¨μ—ˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ ν˜„μž¬ filters_for_model λ₯Ό λ¦¬νŒ©ν† λ§ν•˜μ—¬ μ„ μ–Έλœ 필터에 λŒ€ν•œ ν•„ν„° 생성을 μ‹œλ„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (이것은 fields = ['mask'] κ°€ λΆˆν•„μš”ν•œ μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λŠ” μ„œλΈŒλ„·/마슀크 μ˜ˆμ™€ 관련이 μžˆμŠ΅λ‹ˆλ‹€.

폐쇄 #550

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰