Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tutorial / Help / Documentation] Usage without class based views #183

Open
Rastopapola opened this issue Aug 17, 2021 · 3 comments
Open
Labels
Q&A Questions and answers

Comments

@Rastopapola
Copy link

Hello everyone,

I stumbled upon this project a few weeks ago and was happy to find something that seems very useful for fast and easy modal development. BTW: It is, really. But I had some issues which I tried to fix using the documentation on this git. Sadly the doc is focusing on class-based views only, which is fine, since this is the main target for this package.

Function based views

However, I'm not befriended with class-based views (yet), so I stuck to my regular view methods, you know like

... 
if request.method == 'POST':
   # do stuff
elif request.method == 'GET':
   # do other stuff
else:
   raise NotImplementedError('No stuff')

where you need to handle everything in their if-else branches. But I ran into a wall when I noticed, that after the get-form request there would be two post-form requests by clicking the submit button only once. Indeed, the documentation states, that there can be unsuccessful post requests, where you want to show errors on the modal form and there can be successful post requests, where everything is fine and you only need to save your data on the backend.

So - something that I didn't understood from the documentation - the workflow looks something like this:

  1. GET-request: get a form from the backend
    1. GET-response: render that form into a nice modal form
  2. POST-request: post inserted data to the backend
    1. POST-response: There are errors! or
    2. POST-response: There are no errors!
      1. POST-request: Well, then save that stuff!

And the last two points are important! Something that is handled by the provided classes of this package itself (therefore everything is fine as long as you use everything exactly as intended to be (yeah, shame on me)):

  1. The modal form checks whether the submitted data would be alright, in case we would like to save it
  2. If there are no issues, the same request will be sent again

And there I was, sitting around and thinking: hOw tHE hEll AM i gOiNg tO dIfFeRentTiATe bEtWeEn tHe ChEck ReQuEsT aNd tHe "CoMmIt" oNe?

is_ajax()

And there it is:


That little **** that I hate today but will love tomorrow. That little hint I didn't see all the time. That little thing, that I could simply use in my own code for differentiating between the 'check' request and the 'commit' request:

...
        if request.method == "POST":
            if form.is_valid():
                if not is_ajax(request.META):
                    form.save()
                    messages.success(
                        request,
                        msg_success
                    )
                return HttpResponseRedirect(redirect_url)
...

Using this check my eyes have been opened and finally I understood what happened here exactly - but maybe it was just a regular monday on a tuesday, you know what I mean.

Long story short

However, I hope there are other people out there looking for help with similar questions on how all this does work in detail and how we can use this wonderful package besides of class-based views.

@trco @DarkSir23 @virdiignis @sebastiendementen
It might be helpful to extend your - already nicely written - documentation with another article regarding the usage in function based views. If you want, I surely could support on writing that, just let me know.

@trco trco added the Q&A Questions and answers label Sep 14, 2021
@eddyizm
Copy link

eddyizm commented Nov 16, 2021

Thanks for posting this. I'm looking at this package to help someone and don't see where to add some custom validation on the POST, guessing it has to be on the model but what happens on error as there is nothing on in the view to handle that.

@Rastopapola
Copy link
Author

@eddyizm
That sounds more like you should take a look on the Form and field validation article of Django itself. For my usage, I subclassed the provided ModalForms in this package to build my own logic on top of that, including custom validation. At some point is_valid() always needs to be called and that is your chance to provide custom validation logic in your subclasses form.

@teelei
Copy link

teelei commented Jan 29, 2022

Thanks!

In case someone is struggling, you also need to pass the request object to the form. With formsets, use the form_kwargs argument.

from .forms import MyForm, MyFormset

def my_form_view(request):
    form = MyForm(request=request)
    if request.method == "POST":
        form = MyForm(request.POST, request=request)
        if form.is_valid():
            if not is_ajax(request.META):
                form.save()
                messages.success(
                    request,
                    "Success!"
                )
            return HttpResponseRedirect("/index")
    ...


def my_formset_view(request):
    formset = MyFormset(form_kwargs={'request': request})
    if request.method == "POST":
        formset = MyFormset(request.POST, form_kwargs={'request': request})
        if formset.is_valid():
            if not is_ajax(request.META):
                formset.save()
                messages.success(
                    request,
                    "Success!"
                )
            return HttpResponseRedirect("/index")
    ...

The PopRequestMixin pops it for you (=don't pop it in your form's __init__ method):

class PopRequestMixin(object):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Q&A Questions and answers
Projects
None yet
Development

No branches or pull requests

4 participants