Delete entry from model based on user and id using button

Hi I’m trying to delete an entry from a table filtered by the user_id and the primary_key. I’ve done this in another section of my app but can’t get it working here. Any help would be great.

URLS

urlpatterns = [
    path('my-deposits/', deposit_view, name='mydeposits'),
    re_path('my-deposits/(?P<id>)', deposit_view, name='mydeposits-delete'),
]

VIEWS

def deposit_view(request, id=None):

    deposit = Deposits.objects.filter(user_id=request.user.id).values()

    print(id) # Nothing appears to be printing here

    # Delete Asset Button
    if id and request.method == "POST":
        note = Deposits.objects.filter(user_id=request.user.id, id=id)
        print(note)
        note.delete()
        return redirect('mydeposits')

    context = {
        'deposit': deposit,
    }
    return render(request, 'coinprices/my-deposits.html', context)

HTML

<table class="sort table mb-0 text-sm text-lg-normal table-scrollable">
    <tr>
        <th style="text-align:center">Trans ID</th>
        <th style="text-align:center">Amount</th>
        <th style="text-align:center">Transaction Note</th>
        <th style="text-align:center">Date</th>
    </tr>
    {% for row in deposit %}
    <tr>
        <td style="text-align:center; vertical-align: middle;">{{ row.id }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.amount }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.trans_note }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.date }}</td>
        <td style="background-color:white; border: 1px solid white;">
            <form onsubmit="return confirm('Are you sure?');" action="{% url 'mydeposits-delete' row.id %}" method="POST">
                {% csrf_token %}
                <button class="btn btn-outline-danger btn-sm">Delete</button>
            </form>
        </td>
    </tr>
    {% endfor %}
</table>

MODEL

class Deposits(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    amount = models.FloatField(default=0.0)
    trans_note = models.CharField(max_length=30)
    date = models.DateField(auto_now=True)

FYI - I’ve tried using other variables (e.g. trans_note) and still have the same issue. There is no error, just nothing happens. Suspecting a syntax issue somewhere but have been on this awhile now. Cheers

You have a form inside an html table. That’s invalid html - there should be no expectation that it’s going to work.

Sorry I’m confused with this. I’m currently doing the same approach on another page in my app (i.e. a delete button every row) and it works fine.

All I can think of at this point is to verify what data you have at each step.

For example:

Have you visually verified that these urls are being rendered correctly in the page?

Have you verified that the page being requested is being requested by an authenticated user?

Have you verified on the post that deposit ends up containing a non-empty set?

So the urls are being rendered:
image

the deposits are being rendered on the page:

And yes the user is a super user and there is only one at the moment.

Where is think the issue is here:

    deposit = Deposits.objects.filter(user_id=request.user.id).values()

    print(id) # Nothing appears to be printing here

    # Delete Asset Button

there doesn’t seem to be anything printing. So maybe nothing is being sent. The other app I mentioned is printing the slug that I’m sending.

What are the URLs that you’re seeing being submitted? (When you click on the delete button, what does your server say is the url?)

So if I delete Trans ID 3:

[11/Apr/2022 02:28:33] "POST /coinprices/my-deposits/3 HTTP/1.1" 200 6422

and Trans ID 4:

[11/Apr/2022 02:28:37] "POST /coinprices/my-deposits/4 HTTP/1.1" 200 6422

So yes, the data is being supplied to the url.

Note: id is a built-in function. It’s generally a bad idea to name a variable by that name. (You won’t find any example in the docs using that as a variable name. Yes, using it as an attribute name in a model is a different situation.)

My first recommendation would be to change the parameter name.

I have also tried it with the trans_note column as well as I thought the ID may be an issue but still produces the same results.

Please post the view where you tried that.

VIEW

def deposit_view(request, trans_note=None):

    deposit = Deposits.objects.filter(user_id=request.user.id).values()

    print('Trans Note is here:', trans_note)

    # Delete Asset Button
    if trans_note and request.method == "POST":
        note = Deposits.objects.filter(user_id=request.user.id, trans_note=trans_note)
        print(note)
        note.delete()
        return redirect('mydeposits')

    context = {
        'deposit': deposit,
    }
    return render(request, 'coinprices/my-deposits.html', context)

URLS

urlpatterns = [
    path('my-deposits/', deposit_view, name='mydeposits'),
    re_path('my-deposits/(?P<trans_note>)', deposit_view, name='mydeposits-delete'),
]

HTML

<table class="sort table mb-0 text-sm text-lg-normal table-scrollable">
    <tr>
        <th style="text-align:center">Trans ID</th>
        <th style="text-align:center">Amount</th>
        <th style="text-align:center">Transaction Note</th>
        <th style="text-align:center">Date</th>
    </tr>
    {% for row in deposit %}
    <tr>
        <td style="text-align:center; vertical-align: middle;">{{ row.id }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.amount }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.trans_note }}</td>
        <td style="text-align:center; vertical-align: middle;">{{ row.date }}</td>
        <td style="background-color:white; border: 1px solid white;">
            <form onsubmit="return confirm('Are you sure?');" action="{% url 'mydeposits-delete' row.trans_note %}" method="POST">
                {% csrf_token %}
                <button class="btn btn-outline-danger btn-sm">Delete</button>
            </form>
        </td>
    </tr>
    {% endfor %}
</table>

Server Output

Trans Note is here: 
[11/Apr/2022 02:47:45] "POST /coinprices/my-deposits/this%20is%20a%20test HTTP/1.1" 200 6466
Trans Note is here: 
[11/Apr/2022 02:47:53] "POST /coinprices/my-deposits/this%20is%20another%20test HTTP/1.1" 200 6466

Ok. I had intended for you to only change the name you were using of the variable being supplied in the url - but changing the variable being used is just as good.

As a quick test, try reversing the order of your two urlpattern entries.

Ok, I think I see it. You’ve got a name for the regex parameter, but no pattern specified.
(It’s been a long time since I’ve used a regex path - I find the new path specifiers to be so much easier.)

I’d think it be clearer if you used:
path('my-deposits/<int:pk>', deposit_view, name='mydeposits-delete'),

Ah great that worked! The previous app I mentioned uses this:

re_path('my-dashboard/(?P<slug>[-\w]+)')

Good to know that a pattern must be defined in the URL for re_path(). Thanks for your help