Vues de classes dans Django

Django view points to a function, which can be a problem if you want to change only a bit of functionality. Yes, I could have million keyword arguments and even more if statements in the function, but I was thinking more of an object oriented approach.

Par exemple, j'ai une page qui affiche un utilisateur. Cette page est très similaire à la page qui affiche un groupe, mais ce n'est pas si similaire à utiliser un autre modèle de données. Le groupe a aussi des membres etc ...

Une solution consisterait à pointer les vues vers les méthodes de classe, puis à étendre cette classe. Est-ce que quelqu'un a essayé cette approche ou a une autre idée?

0
ajouté édité
Vues: 6
Bien sûr, merci Alex. J'oublie certains. :-)
ajouté l'auteur engtech, source
@ George2: Pouvez-vous s'il vous plaît examiner vos questions plus anciennes et vérifier celles qui devraient être marquées comme des réponses? Si vous n'avez pas reçu les réponses que vous souhaitez, veuillez éditer et clarifier vos questions. Merci!!
ajouté l'auteur Alex Angas, source

10 Réponses

J'ai joué avec eux un peu et j'ai trouvé des documents utiles dans le passé.

Jetez un coup d'œil sur le forum robot .

Fondamentalement, exécutez le travail «maison» sur le robot, vous avez besoin de la position absolue de chaque axe et cela se trouve sur un autocollant à l'intérieur du contrôleur. À la position d'origine, vous devriez avoir toutes les flèches de référence alignées.

Si la position initiale a été perdue, la mémoire de l'encodeur est perdue. Il compte 4000 points pour chaque révolution - si le mémo de l'encodeur est perdu, il ne sait pas combien sont passés.

Prenez la différence entre la nouvelle et la vieille position de l'encodeur et divisez par 4000 - cela vous donnera combien il est par.

l'exemple donné était:

Nombre de codeurs d'origine: -119771 Nombre de codeurs d'origine (après alignement des repères et réglage des données pour cet axe): -95834 Différence: -23937 Divisé par 4000: 5.98425 Par conséquent, le nombre de révolutions a été de 6 Ma nouvelle position d'origine devrait puis -119771 + (6) x (4000) = -95771

4
ajouté

Consultez le composant WebPart Requête de contenu.

3
ajouté
ouais désolé était pressé sur le chemin d'une réunion! thx kusek
ajouté l'auteur Anonymous User, source
@George Vous devrez peut-être ouvrir une nouvelle question pour cela. Mais je vais vous donner une réponse ici pour le composant WebPart Content Query. blogs.msdn.com/ecm/archive/2006/10/25/…
ajouté l'auteur Isaac Moses, source
Merci Anders! Pourriez-vous me montrer plus d'informations sur la façon d'utiliser "Content Query Web Part" pour créer une liste qui pourrait être affichée dans le site parent et le site enfant (pour afficher le même contenu)?
ajouté l'auteur engtech, source

Les vues génériques seront généralement le chemin à parcourir, mais en fin de compte vous êtes libre de gérer les URL comme vous le souhaitez. FormWizard fait les choses en fonction des classes, tout comme certaines applications pour les API RESTful.

Fondamentalement, avec une URL, on vous donne un tas de variables et de place pour fournir un appelable, ce que vous appelez est entièrement à vous - la façon standard est de fournir une fonction - mais finalement Django ne met aucune restriction sur ce que vous faites.

Je suis d'accord que quelques autres exemples de la façon de faire ce serait bien, FormWizard est probablement l'endroit pour commencer cependant.

0
ajouté

J'ai créé et utilisé mes propres classes de vues génériques, en définissant __ call __ pour qu'une instance de la classe soit appelable. J'aime vraiment ça; Alors que les vues génériques de Django permettent une certaine personnalisation grâce aux arguments de mots clés, les vues génériques OO (si leur comportement est divisé en plusieurs méthodes séparées) peuvent avoir une personnalisation beaucoup plus fine par sous-classe, ce qui me permet de me répéter beaucoup moins. (Je suis fatigué de réécrire la même logique de création / mise à jour à chaque fois que j'ai besoin de modifier quelque chose que les vues génériques de Django ne permettent pas).

J'ai posté du code sur djangosnippets.org .

Le seul véritable inconvénient que je vois est la prolifération des appels de méthodes internes, ce qui peut avoir un impact sur les performances. Je ne pense pas que ce soit très préoccupant; Il est rare que l'exécution de code Python soit votre goulot d'étranglement dans une application Web.

UPDATE: Django's own generic views are now class-based.

UPDATE: FWIW, I've changed my opinion on class-based views since this answer was written. After having used them extensively on a couple of projects, I feel they tend to lead to code that is satisfyingly DRY to write, but very hard to read and maintain later, because functionality is spread across so many different places, and subclasses are so dependent on every implementation detail of the superclasses and mixins. I now feel that TemplateResponse and view decorators is a better answer for decomposing view code.

0
ajouté
L'exécution de Python n'est pas LE goulot d'étranglement, mais pourrait affecter l'évolutivité du site, et globalement la performance. Je suis tellement content que memcache existe!
ajouté l'auteur StefanNch, source

Si vous voulez partager des fonctionnalités communes entre les pages, je vous suggère de regarder les balises personnalisées. Ils sont assez facile à créer , et sont très puissant.

En outre, les modèles peuvent être étendus à partir d'autres modèles . Cela vous permet d'avoir un modèle de base pour configurer la mise en page de la page et de la partager entre d'autres modèles qui remplissent les espaces vides. Vous pouvez imbriquer des modèles à n'importe quelle profondeur. vous permettant de spécifier la mise en page sur des groupes séparés de pages connexes en un seul endroit.

0
ajouté
Je ne pense pas que mettre une trop grande logique dans le modèle est une bonne idée.
ajouté l'auteur Attila O., source

Sauf si vous voulez faire quelque chose d'un peu complexe, l'utilisation des vues génériques est la voie à suivre. Ils sont beaucoup plus puissants que leur nom l'indique, et si vous affichez simplement des données de modèle, les vues génériques feront l'affaire.

0
ajouté

Si vous affichez simplement des données à partir de modèles, pourquoi ne pas utiliser les vues génériques Django ? Ils sont conçus pour vous permettre d'afficher facilement les données d'un modèle sans avoir à écrire votre propre vue et de mapper les paramètres d'URL aux vues, récupérer les données, gérer les cas de bords, restituer la sortie, etc.

0
ajouté

Vous pouvez toujours créer une classe, remplacer la fonction __ call __ , puis pointer le fichier URL vers une instance de la classe. Vous pouvez jeter un oeil à la FormWizard classe pour voir comment cela est fait.

0
ajouté
Le processeur de balisage a mangé vos __. Utilisez \ _ pour masquer le balisage. La classe __call__ est ce qu'on appelle. Le problème est de s'assurer que l'urls.py dispose d'une instance de la classe disponible. Cela rend votre urls.py un peu plus compliqué.
ajouté l'auteur S.Lott, source

J'avais besoin d'utiliser des vues basées sur les classes, mais je voulais être capable d'utiliser le nom complet de la classe dans mon URLconf sans toujours avoir à instancier la classe de vue avant de l'utiliser. Ce qui m'a aidé était une métaclasse étonnamment simple:

class CallableViewClass(type):
    def __call__(cls, *args, **kwargs):
        if args and isinstance(args[0], HttpRequest):
            instance = super(CallableViewClass, cls).__call__()
            return instance.__call__(*args, **kwargs)
        else:
            instance = super(CallableViewClass, cls).__call__(*args, **kwargs)
            return instance


class View(object):
    __metaclass__ = CallableViewClass

    def __call__(self, request, *args, **kwargs):
        if hasattr(self, request.method):
            handler = getattr(self, request.method)
            if hasattr(handler, '__call__'):
                return handler(request, *args, **kwargs)
        return HttpResponseBadRequest('Method Not Allowed', status=405)

Je peux maintenant à la fois instancier des classes d'affichage et utiliser les instances comme des fonctions d'affichage, OU simplement pointer mon URLconf vers ma classe et faire en sorte que la métaclasse instancie (et appelle) la classe d'affichage pour moi. Cela fonctionne en vérifiant le premier argument de __ call __ ? S'il s'agit d'un HttpRequest , il doit s'agir d'une requête HTTP réelle car il serait absurde de tenter d'instancier une classe d'affichage avec une instance HttpRequest .

class MyView(View):
    def __init__(self, arg=None):
        self.arg = arg
    def GET(request):
        return HttpResponse(self.arg or 'no args provided')

@login_required
class MyOtherView(View):
    def POST(request):
        pass

# And all the following work as expected.
urlpatterns = patterns(''
    url(r'^myview1$', 'myapp.views.MyView', name='myview1'),
    url(r'^myview2$', myapp.views.MyView, name='myview2'),
    url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'),
    url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'),
)

(J'ai posté un extrait pour cela à http://djangosnippets.org/snippets/2041/ )

0
ajouté
littéralement génial
ajouté l'auteur Anentropic, source

Vous pouvez utiliser les vues génériques Django. Vous pouvez facilement réaliser la fonctionnalité désirée en profondeur dans les vues génériques de Django

0
ajouté