जवाबों:
बेर द्वारा उत्तर - इसे थ्रेडोकोल्स में संग्रहीत करना - एक बहुत बुरा विचार है। इस तरह से ऐसा करने का कोई कारण नहीं है।
__init__
अतिरिक्त कीवर्ड तर्क लेने के लिए फ़ॉर्म की विधि को ओवरराइड करने का एक बेहतर तरीका है request
। यह अनुरोध को संग्रहीत करता है प्रपत्र , जहाँ इसकी आवश्यकता होती है, और जहाँ से आप इसे अपनी स्वच्छ विधि में एक्सेस कर सकते हैं।
class MyForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self.request ...
और आपके विचार में:
myform = MyForm(request.POST, request=request)
अद्यतन 10/25/2011 : मैं अब इसे डायनामिक तरीके से बनाई गई कक्षा के साथ प्रयोग कर रहा हूं, क्योंकि Django 1.3 कुछ अजीबता प्रदर्शित करता है अन्यथा।
class MyModelAdmin(admin.ModelAdmin):
form = MyCustomForm
def get_form(self, request, obj=None, **kwargs):
ModelForm = super(MyModelAdmin, self).get_form(request, obj, **kwargs)
class ModelFormWithRequest(ModelForm):
def __new__(cls, *args, **kwargs):
kwargs['request'] = request
return ModelForm(*args, **kwargs)
return ModelFormWithRequest
फिर MyCustomForm.__init__
इस प्रकार ओवरराइड करें :
class MyCustomForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyCustomForm, self).__init__(*args, **kwargs)
इसके बाद आप का कोई भी तरीका से अनुरोध वस्तु का उपयोग कर सकते ModelForm
के साथ self.request
।
__new__
जो बाद में कक्षा की __init__
विधि में पारित हो जाएगा । वर्ग का नामकरण ModelFormWithRequest
मुझे लगता है कि इसमें बहुत स्पष्ट है ModelFormMetaClass
।
यदि आप क्लास बेस्ड व्यूज का उपयोग कर रहे हैं, तो फंक्शन बेस्ड व्यूज के बजाय, यह get_form_kwargs
आपके एडिटिंग व्यू में ओवरराइड है। एक कस्टम CreateView के लिए उदाहरण कोड :
from braces.views import LoginRequiredMixin
class MyModelCreateView(LoginRequiredMixin, CreateView):
template_name = 'example/create.html'
model = MyModel
form_class = MyModelForm
success_message = "%(my_object)s added to your site."
def get_form_kwargs(self):
kw = super(MyModelCreateView, self).get_form_kwargs()
kw['request'] = self.request # the trick!
return kw
def form_valid(self):
# do something
उपरोक्त दृश्य कोड request
, फार्म के __init__
कंस्ट्रक्टर फ़ंक्शन के लिए एक कीवर्ड तर्क के रूप में उपलब्ध कराएगा। इसलिए आपके ModelForm
काम में:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
# important to "pop" added kwarg before call to parent's constructor
self.request = kwargs.pop('request')
super(MyModelForm, self).__init__(*args, **kwargs)
request
ऑब्जेक्ट होने के लिए पूरा करते हैं get_form_kwargs
।
self.get_object
? CreateView
फैली हुई है SingleObjectMixin
। लेकिन क्या यह काम करता है या एक अपवाद उठाता है, इस पर निर्भर करता है कि आप एक नई वस्तु बना रहे हैं या किसी मौजूदा को अपडेट कर रहे हैं; यानी दोनों मामलों का परीक्षण करें (और पाठ्यक्रम को हटाने)।
सामान्य aproach एक थ्रेडवेयर का उपयोग करके थ्रेड-स्थानीय संदर्भ में अनुरोध ऑब्जेक्ट को संग्रहीत करना है। फिर आप इसे आप एप में कहीं से भी एक्सेस कर सकते हैं, जिसमें फॉर्म.क्लाइन () विधि भी शामिल है।
Form.clean () पद्धति के हस्ताक्षर को बदलने का मतलब है कि आपके पास स्वयं, Django का संशोधित संस्करण है, जो वह नहीं हो सकता जो आप चाहते हैं।
धन्यवाद मिडलवेयर गणना कुछ इस तरह दिखती है:
import threading
_thread_locals = threading.local()
def get_current_request():
return getattr(_thread_locals, 'request', None)
class ThreadLocals(object):
"""
Middleware that gets various objects from the
request object and saves them in thread local storage.
"""
def process_request(self, request):
_thread_locals.request = request
इस मिडलवेयर को Django डॉक्स में बताए अनुसार रजिस्टर करें
**kwargs
, जिसका अर्थ है कि आपको अनुरोध ऑब्जेक्ट को पास करना होगा MyForm(request.POST, request=request)
।
Django एडमिन के लिए, Django 1.8 में
class MyModelAdmin(admin.ModelAdmin):
...
form = RedirectForm
def get_form(self, request, obj=None, **kwargs):
form = super(MyModelAdmin, self).get_form(request, obj=obj, **kwargs)
form.request = request
return form
मैं व्यवस्थापक को अनुकूलित करते समय इस विशेष समस्या में भाग गया। मैं चाहता था कि एक विशेष क्षेत्र को विशेष व्यवस्थापक की साख के आधार पर मान्य किया जाए।
चूँकि मैं फॉर्म के लिए एक तर्क के रूप में अनुरोध पारित करने के लिए दृश्य को संशोधित नहीं करना चाहता था, इसलिए मैंने जो किया वह निम्न है:
class MyCustomForm(forms.ModelForm):
class Meta:
model = MyModel
def clean(self):
# make use of self.request here
class MyModelAdmin(admin.ModelAdmin):
form = MyCustomForm
def get_form(self, request, obj=None, **kwargs):
ModelForm = super(MyModelAdmin, self).get_form(request, obj=obj, **kwargs)
def form_wrapper(*args, **kwargs):
a = ModelForm(*args, **kwargs)
a.request = request
return a
return form_wrapper
obj=obj
नहींobj=None
'function' object has no attribute 'base_fields'
:। हालांकि, सरल (बिना बंद किए) @ फ्रांस्वा जवाब सुचारू रूप से काम करता है।
आप हमेशा इस विधि का उपयोग नहीं कर सकते (और शायद इसका बुरा अभ्यास), लेकिन यदि आप केवल एक दृश्य में फ़ॉर्म का उपयोग कर रहे हैं, तो आप इसे दृश्य पद्धति के अंदर ही ले जा सकते हैं।
def my_view(request):
class ResetForm(forms.Form):
password = forms.CharField(required=True, widget=forms.PasswordInput())
def clean_password(self):
data = self.cleaned_data['password']
if not request.user.check_password(data):
raise forms.ValidationError("The password entered does not match your account password.")
return data
if request.method == 'POST':
form = ResetForm(request.POST, request.FILES)
if form.is_valid():
return HttpResponseRedirect("/")
else:
form = ResetForm()
return render_to_response(request, "reset.html")
get_form_class
पद्धति में ऐसा करता हूं, अगर मुझे पता है कि मुझे अनुरोध के साथ बहुत सारे सामान करने की आवश्यकता है। बार-बार क्लास बनाने में कुछ ओवरहेड हो सकता है, लेकिन यह सिर्फ इम्पोर्ट टाइम से लेकर रन-टाइम तक चलता है।
द्वारा जवाब डैनियल रोज़मैन का अभी भी सबसे अच्छा है। हालाँकि, मैं कुछ कारणों से कीवर्ड तर्क के बजाय अनुरोध के लिए पहले स्थितीय तर्क का उपयोग करूंगा:
अंत में, मैं एक मौजूदा चर को ओवरराइड करने से बचने के लिए और अधिक अद्वितीय नाम का उपयोग करूंगा। इस प्रकार, मेरा संशोधित जवाब इस तरह दिखता है:
class MyForm(forms.Form):
def __init__(self, request, *args, **kwargs):
self._my_request = request
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self._my_request ...
चीज़केकर से ताजा पनीर @ पिपी: django-requestprovider
मेरे पास इस प्रश्न का एक और उत्तर है कि आपकी आवश्यकता के अनुसार आप उपयोगकर्ता को फॉर्म के स्वच्छ तरीके से एक्सेस करना चाहते हैं। आप यह कोशिश कर सकते हैं। View.py
person=User.objects.get(id=person_id)
form=MyForm(request.POST,instance=person)
forms.py
def __init__(self,*arg,**kwargs):
self.instance=kwargs.get('instance',None)
if kwargs['instance'] is not None:
del kwargs['instance']
super(Myform, self).__init__(*args, **kwargs)
अब आप form.in में किसी भी साफ तरीके से self.instance को एक्सेस कर सकते हैं
जब आप इसे "तैयार" Django वर्ग के विचारों के माध्यम से एक्सेस करना चाहते हैं, CreateView
तो पता करने के लिए एक छोटी सी चाल है (= आधिकारिक समाधान बॉक्स से बाहर काम नहीं करता है)। अपने CreateView
आप में आपको इस तरह कोड जोड़ना होगा:
class MyCreateView(LoginRequiredMixin, CreateView):
form_class = MyOwnForm
template_name = 'my_sample_create.html'
def get_form_kwargs(self):
result = super().get_form_kwargs()
result['request'] = self.request
return result
= संक्षेप में यह request
Django के बनाएँ / अद्यतन विचारों के साथ अपने फॉर्म को पास करने का उपाय है ।