Closed ilyachch closed 4 years ago
I faced a problem, that I watned to check, if value is suitable to some trafaret. And if there are only 2 options, it's ok:
t1 = Trafater()
t2 = Trafaret()
try:
t1.check(value)
func1(value)
except DataError:
t2.check(value)
func2(value)
But if there is more than 3 options, it becomes not so comfortable:
t1 = Trafater()
t2 = Trafaret()
t3 = Trafaret ()
try:
t1.check(value)
func1(value)
except DataError:
try:
t2.check(value)
func2(value)
except DataError:
t3.check(value)
func3(value)
I think, it's more obvious to make it such way:
t1 = Trafater()
t2 = Trafaret()
t3 = Trafaret ()
if t1.is_valid(value):
func1(value)
elif t2.is_valid(value):
func2(value)
if t3.is_valid(value):
func3(value)
Aside usability of is_valid
shortcut – why not to use trafaret like this?
t1 = Trafater() & func1
t2 = Trafaret() & func2
t3 = Trafaret() & func3
data = (t1 | t2 | t3).check(value)
That was only example. In real life there is more than one function call
I'm using it in Django admin get_search_result and i need to filter Queryset based on data i get.
def is_valid(contract: Type[t.Trafaret], value: Any) -> bool:
try:
contract.check(value)
return True
except t.DataError:
return False
class SomeAdmin(admin.Admin):
...
def get_search_results(self, request, queryset, search_term):
if not search_term:
return queryset, False
search_term = search_term.lower()
if is_valid(UuidTrafaret, search_term):
uuid = UUID(search_term)
queryset = queryset.filter(uuid=uuid)
if is_valid(PhoneNumberTrafaret, search_term):
queryset = queryset.filter(user__phone=search_term)
elif is_valid(EmailTrafaret, search_term):
queryset = queryset.filter(user__email=search_term)
return queryset, False
I, myself, prefer it other way
def queryset_t(name):
def adjust_queryset(search_term, context=None)
return context.filter(**{name: search_term})
return adjust_queryset
search_queryset_t = (
UuidTrafaret & queryset_t('uuid')
| PhoneNumberTrafaret & queryset_t('user__phone')
| EmailTrafaret & queryset_t('user__email')
)
class SomeAdmin(admin.Admin):
...
def get_search_results(self, request, queryset, search_term):
if not search_term:
return queryset, False
search_term = search_term.lower()
queryset = search_queryset_t(search_term, context=queryset)
return queryset, False
But I think your way perfectly legit too, so let's merge it. If you will have time, I will be very glad if you will add this method to documentation.
The PR seems redundant. On the other side,
requests
hasresponse.ok
along withresponse.raise_for_status()
. I personally never used this api but I know people who prefer this way.