Question

J'ai un modèle Django avec un grand nombre de champs et plus de 20000 lignes de table. Pour faciliter les URL lisibles par l'homme et la possibilité de décomposer une grande liste en sous-listes arbitraires, j'aimerais disposer d'une URL ressemblant à ceci:

/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....

où "nom" est mappé sur un attribut du modèle et "valeur" est le critère de recherche de cet attribut. Chaque & Quot; nom & Quot; sera traité comme une catégorie pour renvoyer des sous-ensembles d'instances de modèle où les catégories correspondent.

Maintenant, cela pourrait être géré avec les paramètres GET, mais je préfère des URL plus lisibles à la fois pour les utilisateurs et pour les moteurs de recherche. Ces sous-ensembles d'URL seront incorporés à chaque page affichant ce modèle. Il semble donc intéressant de faire l'effort de créer de jolies URL.

Idéalement, chaque paire nom / valeur sera transmise à la fonction d'affichage sous la forme d'un paramètre nommé name1, name2, etc. Cependant, je ne pense pas qu'il soit possible de définir des modèles nommés via le texte correspondant d'une expression rationnelle. Est-ce que je me trompe là-bas?

Il semble donc que j’ai besoin de faire quelque chose comme ceci:

urlpatterns = patterns('',
    url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name="model_browse"),
)

Il semble que cela devrait correspondre à n’importe quel jeu de deux paires nom / valeur. Bien que la correspondance soit réussie, il ne fait que transmettre la paire nom de famille / valeur en tant que paramètres à la fonction de visualisation. Je suppose que chaque correspondance remplace la correspondance précédente. En supposant que le conteneur (?: ...) + le cause, j'ai plutôt essayé un motif répétitif simple:

urlpatterns = patterns('',
    url(r'^browse/([\w]+/)+$', 'app.views.view', name="model_browse"),
)

... et a le même problème, mais cette fois-ci *args n'inclut que le dernier motif correspondant.

S'agit-il d'une limitation du répartiteur d'URL de Django et / ou de la prise en charge des expressions rationnelles de Python? Il semble que l'une ou l'autre de ces méthodes devrait fonctionner. Existe-t-il un moyen d’y parvenir sans coder en dur chaque attribut de modèle possible dans l’URL sous forme de modèle facultatif (. *)?

Était-ce utile?

La solution

Une possibilité que vous pourriez envisager est de faire correspondre la chaîne entière de valeurs possibles dans la partie de modèle d'URL et d'extraire les éléments spécifiques dans votre vue. Par exemple:

urlpatterns = patterns('',
    url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)

def view(request, match):
    pieces = match.split('/')
    # even indexed pieces are the names, odd are values
    ...

Aucune promesse concernant l'expression rationnelle que j'ai utilisée, mais je pense que vous comprenez ce que je veux dire.

(Edité pour essayer de corriger l'expression rationnelle.)

Autres conseils

Je suis d'accord avec Adam, mais je pense que le modèle dans urls.py devrait être:

... r'^browse/(?P<match>.+)/$' ...

Le '\ w' ne fera correspondre que les caractères 'mot', mais le '.' correspond à rien.

La même réponse m'est venue en lisant la question.

Je pense que la vue model_browse est le meilleur moyen de trier les paramètres de la requête et de l'utiliser comme routeur générique.

Je pense que la réponse d'Adam est plus générique que ma solution, mais si vous souhaitez utiliser un nombre fixe d'arguments dans l'URL, vous pouvez également procéder de la manière suivante:

L'exemple suivant montre comment obtenir toutes les ventes d'un jour pour un emplacement en entrant le nom du store et du year, month et day.

urls.py :

urlpatterns = patterns('',
    url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)

Alternativement, vous pouvez également utiliser l'id du magasin en remplaçant (?P<store>.+) par (?P<store>[0-9]+). Notez que location et sales ne sont pas des mots-clés, ils améliorent simplement la lisibilité de l'URL.

views.py

class DailySalesAtLocationListAPIView(generics.ListAPIView):
    def get(self, request, store, year, month, day):
        # here you can start using the values from the url
        print store
        print year
        print month
        print date

        # now start filtering your model

J'espère que cela aidera n'importe qui!

Cordialement,

Michael

J'ai une solution alternative, qui n'est pas très différente de la précédente mais qui est plus raffinée:

url(r'^my_app/(((list\/)((\w{1,})\/(\w{1,})\/(\w{1,3})\/){1,10})+)$'

J'ai utilisé les paramètres d'URL sans nom et un expression rationnelle répétitive. Ne pas obtenir le & Quot; n'est pas une expression régulière valide: plusieurs répétitions & Quot; Je place un mot au début de la liste.

Je travaille toujours sur la vue qui reçoit la liste. Mais je pense que mal 'aller à travers les args ou kwargs .. Vous ne pouvez toujours pas le dire exactement.

Mes 2 cents

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top