Carlos Parisotto
Carlos Parisotto

Reputation: 41

Personalized/random URLs in Python/Django

I'm a Python beginner (and English language beginner too, by the way). I just created a simple form in Python/Django that creates, edit and remove items. I have HTML links that refers to my URLs like:

FILE.HTML:

<INPUT Type="BUTTON" VALUE="Edit" ONCLICK="window.location.href='/edit/{{ object.id }}/'">

URLS.PY:

url(r'^edit/(?P<id>\d+)/$', 'app.views.editobj'),

VIEWS.PY:

def editobj(request, id):

But of course, there's a problem, I wouldn't like people go direct on URL (only if the button was clicked) because somebody could just type on URL: /removeobj/1 and remove the object ID=1. What I would like to do is create differente URLs, maybe random, so the user would never guess what is the URL that the button will open, and of course, that it does work with the ID argument, so when it's goind to edit/remove, opens the right object. I'm Hoping I was clear on my needs. Thanks.

Upvotes: 1

Views: 1684

Answers (2)

Emma
Emma

Reputation: 1081

The simplest way I see to do a "random" url would be to add a UUIDField (https://docs.djangoproject.com/en/1.8/ref/models/fields/#uuidfield or https://github.com/dcramer/django-uuidfield for Django <1.8) with a default to your model.

Your url can then become

url(r'^delete/(?P<uuid>[\da-f-]+)', 'app.views.delete_object', name='delete_obj')

uuid's are virtually impossible to guess.

Now if you don't add extra security to check that the user has the right to delete the object, anyone could still run a robot that would go through every single possible uuid and flush your database.

And if it is just a matter of not "guessing" @Hybrid's solution is probably a better starting point.

Upvotes: 0

Hybrid
Hybrid

Reputation: 7049

Generating random URL's would be highly inefficient, not to mention unnecessarily difficult to implement. The common way to do what you are asking is to POST to a URL. I think you should do a little more reading on Django POSTing, as it will help you get a better understanding of what it does. In any case, here is an example of using this:

urls.py

url(r'^delete/$', 'app.views.delete_object', name="delete_obj"),

views.py

def delete_object(request):
""" Get the ID of an object via POST, then delete it. """
    if request.method == 'POST'  # This makes sure the request is a POST
        obj_id = request.POST['obj_id']
        obj = MODELNAME.objects.get(id=obj_id)  # Use your model name here

        # You can use if conditions here to make sure the object you just
        # retrieved is allowed to be deleted by this user, or in general.

        obj.delete()

        messages.success(request, 'Object successfully deleted!')
    return redirect(reverse('index'))  # Make sure you use a name that exists

.html

<form method="POST" action="{% url 'delete_obj' %}">
    {% CSRF_TOKEN %}
    <input type="hidden" value="{{ obj.id }}" name="obj_id" />
    <button type="submit">Submit</submit>
</form>

You can use more logic in the views.py to make sure that the object is allowed to be deletable, but for the most part, the code I wrote should give you somewhat of an understanding of the way to create a POST -> Delete Object workflow. Feel free to ask questions in the comment section below my answer.

Upvotes: 1

Related Questions