https://htmx.org logo
Join Discord
Powered by
# 🔥-django-htmx
  • l

    limited-pillow-24427

    12/31/2021, 11:30 AM
    @User if you've already my repo, you can also take a look at my
    check_username
    view in accounts (template='accounts/register'). I got proper response (if I'm looking at Network in Dev Tools), see that something is changing in my #username-error div (hx-settling), but content doesnt appear :/
  • u

    user

    12/31/2021, 11:52 AM
    i realized that the regular django form works fine but crispy form does not work with htmx
  • u

    user

    12/31/2021, 11:52 AM
    also, notifications do not get displayed unless you refresh the page
  • c

    cool-camera-13454

    12/31/2021, 1:52 PM
    That's possible, unfortunately I haven't used crispy forms much, so I don't know if they are hard to use with htmx. I would've guessed they are not very different from regular forms, which have a regular
    method=post
    and a
    <button>
    with a
    type=submit
    attribute. If you are going to use regular forms to POST the data, you could simply boost these forms with the
    hx-boost
    attribute (https://htmx.org/attributes/hx-boost/), that could be enough to add the UX you are looking for. So something like this:
    Copy code
    html
    <div hx-boost="true">
      <form method="post" action="some/url/endpoint" hx-push-url="true">
        {% csrf_token %}
        <button type="submit">Submit</button>
      </form>
    </div>
    If you are POSTing from a diferent HTML element using
    hx-post
    , you can do so too. But in that case you have to of course configure your backend so that it returns the exact HTML you want to swap in your frontend. The advantage of "boosted" forms is that HTMX figures out what to swap in your document. I would say, if after POSTing your data, you want to go to a different route/url, use a boosted form. But if you want to stay in the same route/url, use any HTML element that makes sense (like a button or input for example) with an
    hx-post
    attribute swapping a part of your document
  • c

    cool-camera-13454

    12/31/2021, 1:55 PM
    Do you mean notifications using Django messages? Yes unfortunately by default they only trigger with full page refreshes, not with content swapped with AJAX requests, like htmx's. However, I believe someone else mentioned a solution they found for this case some days ago, either in this channel or another htmx channel. Maybe a search with "django messages" yields the information I mention
  • c

    cool-camera-13454

    12/31/2021, 1:56 PM
    I'll check your repo out and let you know if I find anything 😀
  • w

    white-motorcycle-95262

    12/31/2021, 2:47 PM
    Adding to the CSRF questions: it's my understanding that Django changes the expected CSRF token on logout, so am I correct in thinking that solutions such as Step 1 here (https://www.mattlayman.com/blog/2021/how-to-htmx-django/) will not work properly if dealing with users logging in and out? (since the cookie set by
    {{ csrf_token }}
    would be static, and then after someone logs in and out, Django would expect a different token, but HTMX is not updating the part of the template with
    {{ csrf_token }}
  • c

    cool-camera-13454

    12/31/2021, 2:51 PM
    @User So I've checked your repo and tried it on my machine. Unfortunately I get a 500 error when I try to visit the /register/ route, even though I installed your requirements from requirements.txt and perfomed the database migrations 😕 do you use the regular Django server or something else for development? I did try the _/check_username/_ endpoint and it seems to work with a GET request. It displays "The username is available". However, I don't know why you are using a POST request with this route? You want to check if the username exists, right? I think a GET request using query string (to specify the username) makes more sense in this case. Also, if I may make a suggestion, I think it's easier to use an already existing solution for authentication. That way you know that the solution is safe and you don't have to implement all these login, sign up, logout, etc. pages by yourself. I have used Allauth (https://django-allauth.readthedocs.io/en/latest/) and it's great, it pretty much works out of the box. And you can configure it too, for example overriding the templates you want. There are plenty of examples on the internet about the usage of allauth, but if you want you can check out the last template I've been working on, which is a Django + HTMX + Alpine.js starter project template, where I also use allauth for authentication: https://github.com/gmso/django-htmx-alpine-starter
  • c

    cool-camera-13454

    12/31/2021, 3:33 PM
    I've been reading about CSRF protection in Django (https://docs.djangoproject.com/en/4.0/ref/csrf/) and I think I understand a bit better what's going on. As far as I understand, Django generates and sends a
    csrftoken
    cookie on every user login (or if no cookie exists too, I suppose). When sending POST requests, Django's CSRF middleware expects a
    csrfmiddlewaretoken
    as part of the POST request. This token is generated on each template generation, based on the
    csrftoken
    Cookie, that's why this value changes on every page visit. This is the value you obtain using the
    {% csrf_token %}
    template tag. That's why for regular forms, we add this tag inside the form, so that this token is included in the POST request parameters, which will then be checked by the Django's middleware, to see if the POST request is valid or not. For POST requests triggered by htmx's
    hx-post
    , we need a way to send this
    csrfmiddlewaretoken
    information to the server. Instead of adding the parameter to every POST request (like with regular forms), the htmx approach uses a different solution provided by Django for AJAX calls: the
    X-CSRFToken
    header. This is what is added with the event listener on the base template. According to Django's documentation, this alternative should do the same as using the
    {% csrf_token %}
    template tag: > While the above method can be used for AJAX POST requests, it has some inconveniences: you have to remember to pass the CSRF token in as POST data with every POST request. For this reason, there is an alternative method: on each XMLHttpRequest, set a custom X-CSRFToken header (as specified by the CSRF_HEADER_NAME setting) to the value of the CSRF token. This is often easier because many JavaScript frameworks provide hooks that allow headers to be set on every request. To sum up, I think both regular form POST requests and htmx
    hx-post
    requests have the same CSRF protection, they only get their tokens differently
  • w

    white-motorcycle-95262

    12/31/2021, 3:58 PM
    But even if you set the X-CSRFToken header using the template value of
    {% csrf_token %}
    I think it will be the wrong one once you login/logout without a full page refresh. I think we would need to use the
    getCookie
    JS function described here: https://docs.djangoproject.com/en/4.0/ref/csrf/ to get the CSRF token from the cookie, which is updated every request, unlike the template with the
    {% csrf_token %}
    tag
  • l

    limited-pillow-24427

    12/31/2021, 4:16 PM
    https://www.bugbytes.io/posts/django-and-htmx/ yea, I dont know why it's POST
  • f

    flat-flower-95472

    12/31/2021, 5:17 PM
    Man, the fact that this whole discussion about CSRF is even possible is exactly the kind of thing I was worried about in considering using HTMX with Django. I'm hoping that very clear answers can be found, not only for this, but for any of the other security issues Django deals with. If clear answers are found, it seems like someone should post them somewhere they can be reached via googling. Maybe I'd do it myself, by making a dedicated site for HTMX-Django security! But I'd need to really know that there were clear answers!
  • w

    white-motorcycle-95262

    12/31/2021, 6:46 PM
    I don't think it's really that complicated, I think you just need to combine the
    getCookie
    method from Django's documentation with the script in step 1 of https://www.mattlayman.com/blog/2021/how-to-htmx-django/
  • h

    hundreds-camera-24900

    12/31/2021, 7:21 PM
    I've been the simple
    Copy code
    <script>
        document.body.addEventListener('htmx:configRequest', (event) => {
          event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
        })
      </script>
    and haven't had any issues so far
  • h

    hundreds-camera-24900

    12/31/2021, 7:21 PM
    I've noticed that when using a boosted request it registers multiple callbacks
  • h

    hundreds-camera-24900

    12/31/2021, 7:21 PM
    which is a potential leak, but it hasn't practically effected me
  • h

    hundreds-camera-24900

    12/31/2021, 7:22 PM
    and that's worked through login/logout/multiple hx-post calls
  • h

    hundreds-camera-24900

    12/31/2021, 7:25 PM
    using the cookie would be better because it would update the value when the cookie value changes, right?
  • c

    cool-camera-13454

    12/31/2021, 7:28 PM
    I've made a test with both regular forms with
    {% csrf_token %}
    tags and an "htmx login/logout" with
    hx-post
    . I've seen the following: - Every time you login a new CSRF cookie is created when logging in, regardless if you use a regular form or the "htmx login" - If using the "htmx login", the
    csrfmiddlewaretoken
    generated by
    {% csrf_token %}
    does not change, so the event listener will keep sending this same token until a regular HTTP request happens I don't know if not refreshing this is a problem or not. Your proposed solution of using
    getCookie
    seems a good approach to refresh it with every AJAX request. I would say however, that most of the times, after login or logout, you would want to go to a different route/url (like dashboard, home or something like that). So I think that instead of using the "htmx login", it seems easier to use a regular boosted
    <form>
    to trigger that reload of the body (but since it's boosted, you don't see the flash from a page refresh, which is cool)
  • p

    prehistoric-cat-63987

    01/01/2022, 9:35 AM
    I'm sorry for blacking out, something came up. You figured it out?
  • u

    user

    01/01/2022, 2:05 PM
    I'm still stuck and now at the verge of giving it up because 1. django messages work only when there is a full page refresh 2. crispy forms don't work well with htmx 3. updating table ( that use datatables plugin ) with htmx also keep breaking
  • u

    user

    01/01/2022, 2:07 PM
    I guess, i'll probably have to spend some time specifically on htmx and forget trying to implement on my current project with short deadline
  • p

    prehistoric-cat-63987

    01/01/2022, 6:06 PM
    Calm down. I started working with htmx when all I know about it is just hx-post and hx-swap. I completed this same series last two weeks and that's what strengthen me in using it for my current and quiet complex project. I'll just say you should refork the project and start from lesson 1 again, it'll help make you stronger. You can never tell this might be from a mistake deletion you made cause I don't really see anything wrong with your code
  • p

    prehistoric-cat-63987

    01/01/2022, 6:08 PM
    Please don't give up, I didn't know there's something hx-target or hx swap url until I start watching tutorials and reading blogs about HTMX and I can't tell how far I have implement it on my 80% done project that I'm I wanted to use on my portfolio.
  • u

    user

    01/01/2022, 7:52 PM
    I'll get started with the tutorials again soon. thanks for the support.
  • h

    hundreds-camera-24900

    01/02/2022, 4:44 PM
    @User 2/3 aren't really htmx issues and I agree that if you push through it it will help
  • h

    hundreds-camera-24900

    01/02/2022, 4:46 PM
    1 is an htmx issue though - I have an example of how I did that here: https://github.com/Lightmatter/generic-django-conf/blob/3.0/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/util/middleware.py#L6-L25
  • c

    cool-camera-13454

    01/02/2022, 5:37 PM
    @User I agree with what was said here, try not to give up if you can! I'm sure most problems have a solution. If you stick to it you'll end up being successful 😃 But of course if you are under pressure to finish something, it's hard to find the time to experiment and learn. Maybe as you say it's better to leave that for a project where you can afford to spend the time finding solutions to the problems you find along the way
  • c

    cool-camera-13454

    01/02/2022, 5:39 PM
    That's a cool solution! With this Middleware you are able to render Django messages after an htmx request?
  • h

    hundreds-camera-24900

    01/02/2022, 5:54 PM
    yeah, I stick them onto a partial as an oob-swap
1...323334...100Latest