2009-06-11 13 views
13

मेरे पास एक मॉडलफॉर्म है जिसमें एक ऐसा क्षेत्र है जो मॉडल के लिए विदेशीकी मूल्य है जो 40,000 पंक्तियों के रूप में है। डिफ़ॉल्ट मॉडलफॉर्म 40,000 विकल्पों के साथ एक चयन बॉक्स बनाने का प्रयास करता है, जो कहने के लिए कि कम से कम आदर्श नहीं है। और भी अधिक तो जब इस मॉडलफॉर्म का उपयोग फॉर्मेट फैक्ट्री में किया जाता है!मॉडलफॉर्म के लिए raw_id_fields

व्यवस्थापक में, यह "raw_id_fields" का उपयोग करके आसानी से टालने योग्य है, लेकिन ऐसा लगता है कि मॉडलफॉर्म समतुल्य नहीं है। मैं यह कैसे कर सकता हूँ?

class OpBaseForm(ModelForm): 

    base = forms.CharField() 

    class Meta: 
     model = OpBase 
     exclude = ['operation', 'routes'] 
     extra = 0 
     raw_id_fields = ('base',) #does nothing 

पहले बोल्ड लाइन विशाल बोझल selectbox बनाने नहीं कर काम करता है, लेकिन जब मैं इस फार्म के एक fieldset को बचाने की कोशिश, मैं त्रुटि मिलती है: "OpBase

यहाँ मेरी modelform है। आधार "एक" बेस "उदाहरण होना चाहिए। मॉडलफॉर्म को सहेजने के लिए, 'आधार' को आधार उदाहरण होना आवश्यक है। जाहिर है, बेस प्राथमिक कुंजी का स्ट्रिंग प्रस्तुति पर्याप्त नहीं है (कम से कम स्वचालित रूप से नहीं)। बेस उदाहरण के लिए, मेरे फॉर्म को दिए गए स्ट्रिंग को बदलने के लिए मुझे किसी प्रकार की तंत्र की आवश्यकता है। और इस तंत्र को एक फॉर्मेट में काम करना है। कोई विचार? यदि केवल raw_id_fields काम करेगा, तो यह केक के रूप में आसान होगा। लेकिन जहां तक ​​मैं कह सकता हूं, यह केवल व्यवस्थापक में उपलब्ध है।

उत्तर

10

विजेटbase फ़ील्ड के लिए फ़ील्ड प्रकार नहीं, आपको बदलने की आवश्यकता है। मुझे लगता है कि यह काम करेगा:

class OpBaseForm(ModelForm): 
    base = forms.ModelChoiceField(queryset=Base.objects.all(), 
            widget=forms.TextInput) 

    class Meta: 
     model = OpBase 
     ... etc... 
+1

बस स्पष्ट करने के लिए, raw_id_field विशेषता एक मॉडलएडमिन विशेषता है http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields मॉडलफॉर्म विशेषता नहीं है। –

13

तुम भी पूरे raw_id_field व्यवस्थापक विजेट, काम js पॉपअप खोज व्यवस्थापक पृष्ठ है कि के साथ पूरा उपयोग कर सकते हैं। आपको मॉडल फॉर्म की भी आवश्यकता नहीं है।

import string 
from django.contrib.admin.widgets import ForeignKeyRawIdWidget 
from django import forms 
from models import MyModel 

# Have to subclass widget b/c 
# django hardcodes a relative path to Admin Root URL: ../../.. 
class HardcodedURLForeignKeyRawIdWidget(ForeignKeyRawIdWidget): 
    def render(self, *args, **kwargs): 
     original_render = super(HardcodedURLForeignKeyRawIdWidget, 
      self).render(*args, **kwargs) 
     ADMIN_ROOT_URL = "/admin/" 
     return string.replace(original_render,"../../../", ADMIN_ROOT_URL) 


class FieldLookupForm(forms.Form): 
    my_foreignkey_field = forms.CharField(max_length=10, 
     widget=HardcodedURLForeignKeyRawIdWidget(
      MyModel._meta.get_field("foreignkey_field").rel)) 

अपने टेम्पलेट के लिए प्रासंगिक व्यवस्थापक js जोड़ें, और वाइला

{% block header %} 
<script type="text/javascript">window.__admin_media_prefix__ = "/static/admin/";</script> 
<script type="text/javascript" src="/admin/jsi18n/"></script> 
<script type="text/javascript" src="/static/admin/js/core.js"></script> 
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"></script> 
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script> 
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script> 
<script type="text/javascript" src="/static/admin/js/actions.min.js"></script> 
{% endblock %} 
+1

Django 1.4 में ऐसा लगता है जैसे ForeignKeyRawIdWidget का कन्स्ट्रक्टर बदल गया - इस कोड का उपयोग करके इसे __init __() फेंकने का कारण बनता है, केवल 3 तर्क (2 दिए गए) लेते हैं। यदि आपने django.contrib.admin आयात किया है, तो आप admin.site को लापता तर्क के रूप में सीधे विदेशीKeyRawIdWidget पर पास कर सकते हैं और हार्डकोडेड यूआरएल संस्करण के साथ इसे लपेटना नहीं है। – Voltaire

+0

आपको यह काम करने के लिए 'admin.autodiscover() 'करना होगा। मैं इसे एक उत्तर में लिख रहा हूं क्योंकि थोड़ा और गुम है। – chriscauley

+0

क्या होगा यदि आप व्यवस्थापक को रीडायरेक्ट नहीं करना चाहते हैं? – thumbtackthief

12
ऊपर वॉल्टेअर टिप्पणी पर विस्तार करने के लिए

, Django 1.4 समाधान है:

from django.contrib import admin 
admin.autodiscover() 

from django.contrib.admin.widgets import ForeignKeyRawIdWidget 
from django import forms 

from .models import Post, Photo 

class PostForm(forms.ModelForm): 
    photo = forms.ModelChoiceField(
     Photo.objects.all(), 
     widget=ForeignKeyRawIdWidget(Post._meta.get_field("photo").rel,admin.site) 
    ) 

और यहाँ है कैसे आपको केवल अतिरिक्त जावास्क्रिप्ट की आवश्यकता होनी चाहिए:

<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"></script> 

यहां महत्वपूर्ण बात यह है कि आप व्यवस्थापक पर ऑटोडिस्कवर कहते हैं, अन्यथा आपके RawIdWidget के पास कोई लिंक नहीं होगा। इसके अलावा ModelChoiceField को एक क्वेरीसेट की आवश्यकता होती है, जिसका वास्तव में उपयोग नहीं किया जाता है। ModelChoiceField CharField के लिए बेहतर है क्योंकि CharField ठीक से मान्य नहीं है (फोटो उदाहरण को देखने के बजाय आईडी को सहेजने का प्रयास करता है)।

+0

क्या व्यवस्थापक साइट पर रीडायरेक्ट किए बिना ऐसा करने का कोई तरीका है? आदर्श रूप से jquery ऑटो-पूर्ण सुविधा की तरह कुछ? – thumbtackthief

संबंधित मुद्दे