Pregunta

Por lo tanto, mi objetivo es poder filtrar un ModelChoicefield Queryset en mi ModeflaM para incluir solo lugares que Solic. User ha creado.

Mi ModeflaM es simplemente:

class PlaceEventForm(models.ModelForm):
    class Meta:
        model = Event

Me gustaría poder agregar algo como:

def __init__(self, *args, **kwargs):
    super(PlaceEventForm, self).__init__(*args, **kwargs)
    self.fields['place'].queryset = Place.objects.filter(created_by=request.user)

Sin embargo, parece que no puedo encontrar una manera de acceder a la solicitud en ModeflaM.

Mi punto de vista es así:

class PlaceEventFormView(CreateView):
    form_class = PlaceEventForm
    template_name = 'events/event_create.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(PlaceEventFormView, self).dispatch(*args, **kwargs)

No estoy seguro de si esto está cerca de lo que debería hacer, pero lo intenté:

def get_form_kwargs(self):
    kwargs = super(PlaceEventFormView, self).get_form_kwargs()
    kwargs.update({'place_user': self.request.user})
    return kwargs

Pero recibí el error: en eso() obtuve un argumento de palabra clave inesperado 'place_user'

¿Alguna idea sobre éste? ¿O alguien puede pensar en una forma de filtrar mi ModelChoicefield en la vista sin necesidad de transmitir mi solicitud al ModeflaM?

¿Fue útil?

Solución

Necesitas estallar la llave user de kwargs en PlaceEventForm.__init__() método, para evitar que vaya a ModelForm.__init__() método:

Views.py:

class PlaceEventFormView(CreateView):
    form_class = PlaceEventForm
    template_name = 'events/event_create.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(PlaceEventFormView, self).dispatch(*args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(PlaceEventFormView, self).get_form_kwargs()
        kwargs.update({'place_user': self.request.user})
        return kwargs

Forms.py:

class PlaceEventForm(models.ModelForm):
    class Meta:
        model = Event

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('place_user')
        # now kwargs doesn't contain 'place_user', so we can safely pass it to the base class method
        super(PlaceEventForm, self).__init__(*args, **kwargs)
        self.fields['place'].queryset = Place.objects.filter(created_by=user)

Otros consejos

Estoy en un iPhone, pero haz esto:

def get_form(self, form_class):
     form = super(MyView, self).get_form(form_class)
     form.fields['place'].querset = Place....
     return form

¡Vaya, eso fue difícil! ¡Sin apoyo de indención!

Para actualizar la respuesta de Yuji para Django 1.10+ (incluido Django 2.0+), consulte el siguiente ejemplo (tenga en cuenta la firma de método actualizado). El enfoque sugerido de Yuji mantiene el Queryset en la vista junto con la otra lógica comercial, y ayuda a mantener cualquier clase de formulario extendiendo models.ModelForm limpio y sencillo.

def get_form(self, form_class=None):
    if form_class is None:
        form_class = self.get_form_class()
    form = super(MyView, self).get_form()
    form.fields['place'].queryset = Place.objects.filter(created_by=self.request.user)
    return form

Corto:

def get_form(self, form_class=None):
    form = super(MyView, self).get_form(form_class)
    form.fields['place'].queryset = Place.objects.filter(created_by=self.request.user)
    return form
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top