简体   繁体   中英

Using reverse url lookup in django template with keyword arguements

I would like to use the reverse url lookup available in a django template using keyword arguments instead of positional ones.

I have it working using positional arguments just fine as such:

HTML:

    <a href="{% url 'download' customer.pk %}">download</a>

URL:

    (r'^generator/download/(?P<customer_id>\d+)/$', 'generator.views.send_file', name='download'),

View definition:

    def send_file(request, customer_id):

The problem is that I am noticing a security flaw in that now anyone can simply enter as a url like:

    /generate/download/<any number>/

and download a file that is meant only for someone else. I understand that this risk might be able to be mitigated by using user permissions etc, but I still would like to add another layer of security just in case. Maybe I am wrong in my thinking that a keyword argument is safer in this regard because it is not simply available to be passed in the url... But that is what I am thinking.

The code as I think it should work looks like:

HTML:

    <a href="{% url 'download' customer_id=customer.pk %}">download</a>

URL:

    (r'^generator/download/$', 'generator.views.send_file', name='download'),

View definition:

    def send_file(request, customer_id=None):
        customer = get_object_or_404(Customer, pk=customer_id)
        ... other code

meaning if /generate/download/ is entered in the url (without the accompanying kwarg) it would just give them 404.

but I am getting the following error when I try to use this code:

Reverse for 'download' with arguments '()' and keyword arguments '{u'customer_id': 33}' not found. 1 pattern(s) tried: ['generator/download/$']

I'm sure it is something silly that I simply passed over in the django url dispatcher docs, or perhaps it is in the way I am defining my view (perhaps I need **kwargs as the argument?) but I can't seem to find it for the life of me.

Your help is much appreciated.

Your assumption is unfortunately completely wrong. Keyword arguments are passed in the URL, they are simply sent to the view function in a different way - in kwargs instead of args.

The simplest way to solve your problem is just to check the user in the download function itself.

def download(request, pk):
    obj = Download.objects.get(pk)
    if obj.customer_id != request.user.id:
        return HttpResponseForbidden()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM