2010-08-10 4 views
1

J'ai un modèle qui doit stocker les URL qui feront partie de l'environnement Django. Si je stockais des URL normales, j'utiliserais models.URLField, et utiliserais verify_exists pour m'assurer que l'URL existe réellement.Django et les URL locales de test existent

Cependant, cela ne marche pas très bien en développement, puisque le serveur dev est mono-thread, il se bloque indéfiniment, car il ne peut pas traiter deux requêtes à la fois.

J'espérais faire quelque chose en utilisant resolve(), mais je suis mal à s'adapter la fonction myview à la fin de cette page de documentation à une version qui ne prend pas une demande, puisque je veux vérifier qu'une URL locale donnée peut être résolu, et appelé sans 404 étant soulevé, d'une session vide.

J'espérais faire cela avec un validator, quelque chose comme ceci:

def validate_local_url(value): 
    try: 
     view, args, kwargs = resolve(value) 
     view(*args, **kwargs) 
    except Resolver404: 
     raise ValidationError(u'%s is not a local URL (not a valid URL)' % value) 
    except Http404: 
     raise ValidationError(u'%s is not a local URL (does not exist)' % value) 

Cependant, cela ne fonctionne pas sans objet request valide étant passé dans kwargs. Comment générer un objet de requête factice (vide)? J'ai essayé juste en utilisant django.http.HttpRequest.

+0

À quel point voulez-vous être strict? Voulez-vous qu'il soit impossible de lier un enregistrement manquant ou supprimé, ou voulez-vous simplement vous assurer qu'il correspond à une vue de votre application? –

+0

@Jordan - Je veux m'assurer qu'il correspond à une certaine vue, et avec les arguments que les valeurs de 'resolve' passées à la vue, ne soulève pas un' Http404'. –

Répondre

0

Juste une idée folle, pas sûr si ce sera utile. Avez-vous envisagé de nommer les URL et d'utiliser reverse()? Reverse fonctionnera si l'URL est valide et échouera lorsqu'elle ne l'est pas.

+0

Je ne suis pas sûr de comment cela fonctionnerait - les utilisateurs auraient besoin de connaître les noms des vues et comment ils obtiennent leurs paramètres. –

0

Êtes-vous cool avec l'utilisation du django test Client?

Si oui, cela devrait le faire:

from django.test.client import Client 

def validate_local_url(path): 
    c = Client() 
    try: 
     resp = c.get(path) 
     if resp.status_code == 404: 
      raise ValidationError(u'%s is not a local URL (does not exist)' % value) 
    except: 
     raise ValidationError(u'%s is not a local URL (not a valid URL)' % value) 

juste, vous savez, assurez-vous que sous peine de mort que validate_local_url peut jamais être appelé par une demande GET locale, sinon quelqu'un peut mettre trivialement votre serveur sur une boucle infinie:

# urls.py 
url('^infinite_loop/$', 'myapp.infinite_loop', 'infinite_loop') 

#views.py 
def infinite_loop_view(request, template_name="blah.html", form_class=MyForm): 
    my_form = form_class(request.REQUEST or None) # yes, admittedly this is dumb 
    if my_form.is_valid(): 
     return HttpResponse("Congratulations! Your path was totally valid.") 
    return render_to_response(template_name, locals(), RequestContext(request)) 

Et puis:

http://example.com/infinite_loop/?path_field=infinite_loop

+0

Bien que je suppose que même alors ce serait bien, puisque le second appel n'enverrait pas les variables de chemin, non? Même ainsi, je me méfierais de cette décision. Personnellement, je serais content de m'assurer qu'ils ont créé une URL locale qui pointe vers une URL valide (c'est-à-dire qui ne déclenche pas Resolver404) et qui acceptent le 404 occasionnel. –