Normalmente, utilizzo un metodo dispatch
di una vista basata su classi per impostare alcune variabili iniziali o aggiungere una logica basata sulle autorizzazioni dell'utente.Django: una visualizzazione basata su classi con mixin e metodo di invio
Per esempio,
from django.views.generic import FormView
from braces.views import LoginRequiredMixin
class GenerateReportView(LoginRequiredMixin, FormView):
template_name = 'reporting/reporting_form.html'
form_class = ReportForm
def get_form(self, form_class):
form = form_class(**self.get_form_kwargs())
if not self.request.user.is_superuser:
form.fields['report_type'].choices = [
choice for choice in form.fields['report_type'].choices
if choice[0] != INVOICE_REPORT
]
return form
Esso funziona come previsto: quando un utente anonimo visita un pagine, il metodo di LoginRequiredMixindispatch
si chiama, e poi reindirizza l'utente alla pagina di login.
Ma se voglio aggiungere alcuni permessi per questa vista o impostare alcune variabili iniziali, per esempio,
class GenerateReportView(LoginRequiredMixin, FormView):
def dispatch(self, *args, **kwargs):
if not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)
in alcuni casi non funziona, perché dispatch
metodi delle mixins, che la vista eredita, non è stato ancora chiamato. Così, per esempio, di essere in grado di chiedere i permessi degli utenti, devo ripetere la convalida da LoginRequiredMixin
:
class GenerateReportView(LoginRequiredMixin, FormView):
def dispatch(self, *args, **kwargs):
if self.request.user.is_authenticated() and not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)
Questo esempio è semplice, ma a volte ci sono una logica più complessa in un mescolamento: si verifica la presenza di permessi, fa alcuni calcoli e li memorizza in un attributo di classe, ecc.
Per ora lo risolvo copiando del codice dal mixin (come nell'esempio sopra) o copiando il codice dal metodo dispatch
della vista ad un altro mixin e ad ereditarlo dopo il primo per eseguirli in ordine (il che non è carino, perché questo nuovo mixin è usato solo da una vista).
Esiste un modo corretto per risolvere questo tipo di problemi?
prima chiamata '' super (GenerateReportView, self) .dispatch (* args, ** kwargs) ''. poi fai il resto del lavoro all'interno della spedizione che stai sovrascrivendo –
@MihaiZamfir Non funzionerà perché, ad esempio, '' LoginRequiredMixin'' restituisce un oggetto '' HttpResponseRedirect'', quindi se lo memorizziamo in una variabile, non eseguirà un reindirizzamento alla vista di accesso finché non restituiremo questa variabile alla fine del metodo '' dispatch''. – vero4ka
ma è possibile verificare se la risposta è un reindirizzamento, quindi continuare con la spedizione –