Solución:
Editar: tenga en cuenta que esto ya no es válido para ninguna versión de Django superior a 1.5
Supongo que desea verificar si el archivo realmente existe, no si solo hay un objeto (que es solo una simple declaración if)
Primero, recomendaré buscar siempre a través del código fuente de Django porque encontrará un gran código que podría usar 🙂
Supongo que quiere hacer esto dentro de una plantilla. No hay una etiqueta de plantilla incorporada para validar una URL, pero básicamente podrías usarla URLValidator
class dentro de una etiqueta de plantilla para probarlo. Simplemente:
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
validate = URLValidator(verify_exists=True)
try:
validate('http://www.somelink.com/to/my.pdf')
except ValidationError, e:
print e
los URLValidator
la clase escupirá el ValidationError
cuando no puede abrir el enlace. Usa urllib2
para abrir realmente la solicitud, por lo que no solo se usa la verificación básica de expresiones regulares (sino que también lo hace).
Puede colocar esto en una etiqueta de plantilla personalizada, que descubrirá cómo crear en los documentos de django y listo.
Espero que sea un comienzo para ti.
Problema
from django.core.validators import URLValidator
dice que www.google.ro
no es válido. Lo cual está mal en mi punto de vista. O al menos no lo suficiente.
¿Cómo resolverlo?
La pista es mirar el código fuente de models.URLField
, verás que usa forms.FormField
como validador. Que hace más que URLValidator
desde arriba
Solución
Si quiero validar un url
igual que http://www.google.com
o me gusta www.google.ro
, Haría lo siguiente:
de django.forms importar URLField
def validate_url(url):
url_form_field = URLField()
try:
url = url_form_field.clean(url)
except ValidationError:
return False
return True
Encontré esto útil. Quizás ayude a alguien más.
Cualquier cosa basada en el verify_exists
parámetro a django.core.validators.URLValidator
dejará de funcionar con Django 1.5; la documentación amablemente no dice nada sobre esto, pero el código fuente revela que usar ese mecanismo en 1.4 (la última versión estable) conduce a un DeprecationWarning
(verá que se ha eliminado por completo en la versión de desarrollo):
if self.verify_exists:
import warnings
warnings.warn(
"The URLField verify_exists argument has intractable security "
"and performance issues. Accordingly, it has been deprecated.",
DeprecationWarning
)
También hay algunas peculiaridades extrañas con este método relacionadas con el hecho de que utiliza un HEAD
solicitud para verificar las URL: eficiente en el ancho de banda, claro, pero algunos sitios (como Amazon) responden con un error (para HEAD
, donde el equivalente GET
habría estado bien), y esto conduce a resultados falsos negativos del validador.
También recomendaría (muchas cosas han cambiado en dos años) no hacer nada con urllib2
en una plantilla: esta es la parte completamente incorrecta del ciclo de solicitud / respuesta para desencadenar operaciones potencialmente de larga duración: considere lo que sucede si la URL existe, pero un problema de DNS causa urllib2
tomar 10 segundos para resolverlo. ¡BAM! 10 segundos adicionales instantáneos en la carga de su página.
Yo diría que la mejor práctica actual para hacer que tareas de ejecución prolongada como esta sean asincrónicas (y por lo tanto no bloqueen la carga de la página) es usar django-celery
; hay un tutorial básico que cubre el uso pycurl
para consultar un sitio web, o podría ver cómo Simon Willison implementó las tareas de apio (diapositivas 32-41) con un propósito similar en Lanyrd.