Django वर्ग-आधारित दृश्य: मैं as_view पद्धति में अतिरिक्त पैरामीटर कैसे पास करूं?


95

मेरे पास एक कस्टम क्लास-आधारित दृश्य है

# myapp/views.py
from django.views.generic import *

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

मैं इस तरह से स्लग पैरामीटर (या देखने के लिए अन्य पैरामीटर) में पारित करना चाहता हूं

MyView.as_view(slug='hello_world')

क्या मुझे ऐसा करने में सक्षम होने के लिए किसी भी तरीके को ओवरराइड करने की आवश्यकता है?

जवाबों:


113

यदि आपका urlconf कुछ इस तरह दिखता है:

url(r'^(?P<slug>[a-zA-Z0-9-]+)/$', MyView.as_view(), name = 'my_named_view')

फिर स्लग आपके दृश्य कार्यों (जैसे 'get_queryset') के अंदर उपलब्ध होगा:

self.kwargs['slug']

18
मामले में एक अपवाद से बचने के लिए यह एक वैकल्पिक पैरामीटर है: उपयोगself.kwargs.get('slug', None)
रिसादिना

6
बस उत्सुक, कब / कहाँ यह "self.kwargs" आबादी है? मैं बेस क्लास फ़ंक्शन की तलाश कर रहा हूं जहां यह सेट है।
बिनीथब

में github.com/django/django/blob/master/django/views/generic/... मेंclass View: def as_view(cls, **initkwargs): def view(request, *args, **kwargs):
अपोलो डाटा

सवाल का जवाब नहीं।
कीर्ति के

इस विधि को अब हटा दिया गया है, अब आप इसका उपयोग कर सकते हैंurl('<slug:slug>', MyView.as_view(), name='my_named_view')
राहत जमां

91

as_viewविधि के लिए पारित किया गया हर पैरामीटर दृश्य वर्ग का एक उदाहरण चर है। इसका मतलब है slugकि एक पैरामीटर के रूप में आपको इसे अपने उप-वर्ग में उदाहरण चर के रूप में बनाना होगा:

# myapp/views.py
from django.views.generic import DetailView

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel
    # additional parameters
    slug = None

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

वह MyView.as_view(slug='hello_world')काम करना चाहिए ।

यदि आप कीवर्ड के माध्यम से चर पास कर रहे हैं, तो श्री एरिकसन ने जो सुझाव दिया है उसका उपयोग करें : https://stackoverflow.com/a/11494666/9303


2
कभी नहीं import *। अपनी पोस्ट संपादित की।
होल्स

भविष्य के पाठकों के ज्ञान के लिए @holms, PEP8 का कहना है कि "वाइल्डकार्ड आयात (<मॉड्यूल> आयात ) से बचा जाना चाहिए"। चाहिए के रूप में के रूप में मजबूत नहीं है और यह एक उदाहरण है, लेकिन हाँ निश्चित रूप से * वाइल्डकार्ड आयात से बचना चाहिए : python.org/dev/peps/pep-0008/#imports

कहीं भी कुछ भी नहीं है, हम अपनी इच्छानुसार किसी भी चीज को तोड़ सकते हैं, लेकिन pep8 सिर्फ प्रथाओं की सिफारिश है, और अजगर समुदाय में इन सभी प्रथाओं का अधिक से अधिक उपयोग करने के लिए अंगूठे का एक नियम है, ताकि आगे की समस्याओं से बचा जा सके। जब मैं अपना कोड करता हूं तो मेरा लिंटर हमेशा खाली रहता है :) कोई बात नहीं।
होम्स

वास्तविक चर के लिए स्लग = 'हेल्लो_वर्ल्ड' का मूल्य क्या है?
गोंजालो डामरा

19

यह ध्यान देने योग्य है कि आपको get_object()कीवर्ड arg के रूप में पारित किए गए स्लग के आधार पर किसी ऑब्जेक्ट को देखने के लिए ओवरराइड करने की आवश्यकता नहीं है - आप https://docs.djangoproject.com/en/1.5/ref/ के गुणों का उपयोग कर सकते हैं SingleObjectMixin वर्ग आधारित-विचारों / mixins-एकल वस्तु / # singleobjectmixin

# views.py
class MyView(DetailView):
    model = MyModel
    slug_field = 'slug_field_name'
    slug_url_kwarg = 'model_slug'
    context_object_name = 'my_model'

# urls.py
url(r'^(?P<model_slug>[\w-]+)/$', MyView.as_view(), name = 'my_named_view')

# mymodel_detail.html
{{ my_model.slug_field_name }}

(दोनों slug_fieldऔर slug_url_kwargडिफ़ॉल्ट 'slug')


1
क्या मुझे अपना उत्तर विकि उत्तर में बदल देना चाहिए और उसमें अपना कोड जोड़ना चाहिए?

15

यदि आप टेम्प्लेट के संदर्भ के लिए ऑब्जेक्ट जोड़ना चाहते हैं तो आप ओवरराइड कर सकते हैं get_context_dataऔर इसके संदर्भ में जोड़ सकते हैं । अनुरोध भी स्वयं का एक हिस्सा है जब आपको अनुरोध की आवश्यकता होती है ।

def get_context_data(self, **kwargs):
        context = super(MyTemplateView, self).get_context_data(**kwargs)
        if 'slug' in self.kwargs:
            context['object'] = get_object_or_404(MyObject, slug=self.kwargs['slug'])
            context['objects'] = get_objects_by_user(self.request.user)

        return context

क्या है MyObject?
रोब क्वासोस्की

13

आप urls.py https://docs.djangoproject.com/en/1.7/topics/http/urls/#passing-extra-options-to-view-functions से पैरामीटर पास कर सकते हैं

यह जेनेरिक विचारों के लिए भी काम करता है। उदाहरण:

url(r'^$', views.SectionView.as_view(), { 'pk': 'homepage', 'another_param':'?'}, name='main_page'),

इस मामले में दृश्य के लिए दिए गए पैरामीटर जरूरी नहीं कि व्यू वर्ग के उदाहरण चर हों। इस पद्धति का उपयोग करके आपको YourView मॉडल में डिफ़ॉल्ट पृष्ठ नाम को हार्डकोड करने की आवश्यकता नहीं है, लेकिन आप इसे urlconf से एक पैरामीटर के रूप में पारित कर सकते हैं।


धन्यवाद, मैं इसके लिए काफी समय से खोज कर रहा था!
इलजा

7

जैसा कि यारोस्लाव निकितेंको ने कहा है , यदि आप व्यू क्लास में एक नया इंस्टेंस वेरिएबल हार्डकोड नहीं करना चाहते हैं, तो आप इस तरह से फंक्शन देखने के लिए अतिरिक्त विकल्प पास कर सकते हैंurls.py :

url(r'^$', YourView.as_view(), {'slug': 'hello_world'}, name='page_name')

मैं सिर्फ यह देखना चाहता था कि इसे कैसे इस्तेमाल किया जाए। आप निम्न विधियों में से एक को लागू कर सकते हैं:

# If slug is optional
def the_function(self, request, slug=None):
    # use slug here

# if slug is an optional param among others
def the_function(self, request, **kwargs):
    slug = kwargs.get("slug", None)
    other_param = kwargs.get("other_param", None)

# If slug is required
def the_function(self, request, slug):
    # use slug here

1
मैं इसे यारोस्लाव निकितेंको के जवाब में संपादित करना चाहता था , लेकिन इसे अस्वीकार कर दिया गया था, इसलिए मैंने अपना खुद का बनाया क्योंकि मुझे लगा कि यह लापता जानकारी थी जब मुझे इसकी आवश्यकता थी।
एमिल बर्जरॉन

आपके पोस्ट के लिए शुक्रिया! मुझे याद नहीं है कि क्या वह था जिसने आपके संपादन को अस्वीकार कर दिया था और क्यों।
यारोस्लाव निकितेंको

@YaroslavNikitenko हिनडाइट में, यह एक एडिट के लिए बहुत बड़ा था और एक नए उत्तर के रूप में एक उत्तर के रूप में सबसे अच्छा था।
एमिल बर्जरॉन

@EmileBergeron प्रारंभिक प्रश्न DetailViewकक्षा जैसे सामान्य विचारों के बारे में था । क्या आप बता सकते हैं कि वहाँ इसका उपयोग कैसे किया जाए?
बर्टेल्टरमैन

3

Django 3.0 के लिए, यह मेरे लिए काम कर रहा है:

# myapp/views.py
from django.views.generic import DetailView

class MyView(DetailView):
    template_name = 'detail.html'
    slug = None

    def get_object(self, queryset=None):
        self.slug = self.kwargs.get('slug', None)
        return queryset.get(slug=self.slug)

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('slug/<slug:slug>/', views.MyView.as_view(), name='myview_by_tag'),
]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.