Doubt with Django 2.0 views and urls

Asked

Viewed 325 times

0

How best to do these functions in the views.py, or it has to be that way?

from django.shortcuts import render


def index(request):
    return render(request, 'contas/index.html')

def cadastro(request):
    return render(request, 'contas/cadastro-clientes.html')

def contato(request):
    return render(request, 'contas/contato.html')

def sobre(request):
    return render(request, 'contas/quem-somos.html')

def novasenha(request):
    return render(request, 'contas/nova-senha.html')

def base(request):
    return render(request, 'contas/base.html')

def entenda(request):
    return render(request, 'contas/entenda.html')



Quanto a urls.py, também seria a melhor forma deixar meu código da seguinte forma.

from django.contrib import admin
from django.urls import path
from contas.views import index, cadastro, contato, sobre, novasenha, base, entenda
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
    path('cadastro/', cadastro, name='cadastrar'),
    path('contato/', contato, name='contato'),
    path('sobre/', sobre, name='sobre'),
    path('novasenha/', novasenha, name='novasenha'),
    path('entenda/', entenda, name='entenda'),
    path('', base, name='base')


]
  • "better" in relation to what?

  • It’s like documentation, what you want to improve?

  • from accounts.views import index, registration, contact, about, newpassword, base, understand. Here, for example: if I had 30 pages, I would have to insert them all?

1 answer

1

From what I understand, after your comment, you just want to make the code more elegant in the file urls.py.

Instead of:

...
from contas.views import index, cadastro, contato, sobre, novasenha, base, entenda
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
    path('cadastro/', cadastro, name='cadastrar'),
    path('contato/', contato, name='contato'),
    path('sobre/', sobre, name='sobre'),
    ...
]

You can only import the module file views and use it with namespace in the declaration:

...
from django.urls import path
from contas import views

urlpatterns = [
        path('admin/', admin.site.urls),
        path('', index),
        path('cadastro/', views.cadastro, name='cadastrar'),
        path('contato/', views.contato, name='contato'),
        path('sobre/', views.sobre, name='sobre'),
        ...
    ]

And that would be recommended.

If you really prefer, there is no magic, url_patterns are a normalizinho Python object - a list of objects of type "path" where the first parameter is the desired url pattern, the second object that will be the view itself (which can be a function, a class or another chargeable object)and the third, a name for the view. That is: you can generate this list programmatically from the introspection of the "views" module - instead of declaring all static in the file. It’s a case where in general "explicit" is better than implicit - but it might save you having to edit one more file every time you create a new view - in which case, the code might be something like:

from contas import views

urlpatterns = [
   path('admin/', admin.site.urls),
   path('', index),
]

for name, obj in views.__dict__.items():
    if callable(obj):
        urlpatterns.append(path(f"{name}/", obj, name)

With this code, all functions in your "views" file will have an automatically generated URL.

Note that while this is a rather dangerous practice, since it does not distinguish functions that you may not want to use as views, and etc..., the technique allows you to realize how simple it is to do something in Django to be used as a "decorator for views", as is done in other frameworks, like Flask.

In this case, it can be a very simple decorator, who does not "envelop" the decorated function, just adds to it the desired data:

def autoview(path=None, name=None):
    def decorate(func):
         # acrescenta o atributo "autoview" na função, 
         # que é um objeto Python normal:

         func.autoview = {
             "path": path or f"{func.__name__}/",
             "name": name or func.__name__
         }
         return func
    return decorate

Dai you can write your views file in this style:

from utils import autoview
...

@autoview(name="cadastrar")
def cadastro(request):
    return render(request, 'contas/cadastro-clientes.html')

@autoview()
def contato(request):
    return render(request, 'contas/contato.html')

And in.py urls, a variant of the above suggestion, to use ". autoview":

for name, obj in views.__dict__.items():
    if hasattr(object, "autoview"):
        urlpatterns.append(path(obj.autoview["path"], obj, obj.autoview["name"])
  • From what you understand, wouldn’t it be a good practice to do it that way that you presented it because someone might be able to insert another file? example www.meusite.com/attack.html Would that be it? someone inserted an html attack and it would accept?

  • Thank you very much.

  • Other help if possible. how would Django change the title of each page. Ex: when you click register, it changed the html title to the registration page.

  • Django is not PHP - there is no way someone can insert a file into the server if they cannot access the server by other means. If the person already has access to the server with permission to create files where the app is, it doesn’t matter if they need a file only or not in terms of security. The suggestions here have no impact from a security point of view - and the latter is a prescription to use view paradgima by decorator, which is commonly used in other frameworks, also in Django.

  • For "title" just use html tag <title> in your HTML template, and fill it with some view variable, as it does with any other data.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.