I tried the spatie package, but never really used it because I prefer handling the authorizations manually.
You can do amazing authorizations just with the policies.
Gates are more used for global roles like admin, member, ... and policies for authorization like can create, can update, ... But in fact policies can do both.
You can create groups, then create permissions inside each group (each group has its own permissions)
Then when create a new user, assign this user to that specific group, wich gonna inherit those permissions from.
Sometime, there's confusion in Django for people coming from other frameworks, they usually deal with "Roles" rather than "Groups". I'n django it's groups https://mobdro.bio/
Spatie packages are great and they'll always save you time and money. It all depends on your definition of the word 'best'.
If by 'best' you mean, it works as it says it's documented and does so very well, go for Spatie.
If by 'best' you mean, have to work out how to implement the same thing that's already been done by Spatie, testing it yourself and ensuring it works flawlessly and you have endless budget... do it yourself.