2010-11-30 14 views
10

Django व्यवस्थापक filter_horizontal सेटिंग कई से अधिक संबंधों को संपादित करने के लिए एक अच्छा विजेट देता है। लेकिन यह एक विशेष सेटिंग है जो फ़ील्ड की सूची चाहता है, इसलिए यह केवल (व्यवस्थापक के लिए) मॉडल पर उपलब्ध है जो ManyToManyField को परिभाषित करता है; मैं अन्य मॉडल पर उसी विजेट को कैसे प्राप्त कर सकता हूं, रिश्ते को पीछे की ओर पढ़ रहा हूं?Django व्यवस्थापक में ManyToManyField के दोनों दिशाओं तक कैसे पहुंचे?

मेरे मॉडल इस तरह दिखेगा (User/UserProfile जटिलता की अनदेखी करने के लिए स्वतंत्र महसूस, यह वास्तविक उपयोग मामला है, हालांकि):

class Site(models.Model): 
    pass 
class UserProfile(models.Model): 
    user = models.OneToOneField(to=User,unique=True) 
    sites = models.ManyToManyField(Site,blank=True) 

मैं

साथ UserProfile के लिए व्यवस्थापक प्रपत्र पर एक अच्छा विजेट प्राप्त कर सकते हैं
filter_horizontal = ('sites',) 

लेकिन यह नहीं देख सकता कि Site व्यवस्थापक पर समकक्ष कैसे प्राप्त करें।

मैं भी SiteAdmin को एक इनलाइन जोड़कर हिस्सा तरह से प्राप्त कर सकते हैं, के रूप में परिभाषित:

class SiteAccessInline(admin_module.TabularInline): 
    model = UserProfile.sites.through 

यह गोल चक्कर और असुविधाजनक हालांकि है; विजेट कई से अधिक रिश्तों को प्रबंधित करने के लिए बिल्कुल सहज नहीं है।

अंत में, वहाँ एक चाल described here जो Site पर एक और ManyToManyField को परिभाषित करने और यकीन है कि यह एक ही डेटाबेस तालिका के लिए अंक बनाने (और कुछ हुप्स के माध्यम से कूद क्योंकि Django वास्तव में विभिन्न मॉडलों में एक ही वर्णन करने पर विभिन्न क्षेत्रों के लिए नहीं बनाया गया है शामिल है डेटा)। मुझे उम्मीद है कि कोई मुझे कुछ क्लीनर दिखा सकता है।

उत्तर

7

यहाँ http://blog.abiss.gr/mgogoulos/entry/many_to_many_relationships_and करने और http://code.djangoproject.com/ticket/5247

from django.contrib import admin as admin_module 

class SiteForm(ModelForm): 
    user_profiles = forms.ModelMultipleChoiceField(
     label='Users granted access', 
     queryset=UserProfile.objects.all(), 
     required=False, 
     help_text='Admin users (who can access everything) not listed separately', 
     widget=admin_module.widgets.FilteredSelectMultiple('user profiles', False)) 

class SiteAdmin(admin_module.ModelAdmin): 
    fields = ('user_profiles',) 

    def save_model(self, request, obj, form, change): 
     # save without m2m field (can't save them until obj has id) 
     super(SiteAdmin, self).save_model(request, obj, form, change) 
     # if that worked, deal with m2m field 
     obj.user_profiles.clear() 
     for user_profile in form.cleaned_data['user_profiles']: 
      obj.user_profiles.add(user_profile) 

    def get_form(self, request, obj=None, **kwargs): 
     if obj: 
      self.form.base_fields['user_profiles'].initial = [ o.pk for o in obj.userprofile_set.all() ] 
     else: 
      self.form.base_fields['user_profiles'].initial = [] 
     return super(SiteAdmin, self).get_form(request, obj, **kwargs) 

यह filter_horizontal सेटिंग के रूप में एक ही विजेट का उपयोग करता है से लिया एक Django बग के लिए एक फिक्स के साथ एक (कम या ज्यादा) साफ समाधान है, धन्यवाद, लेकिन में हार्ड-कोडेड फार्म।

+0

बहुत बहुत धन्यवाद! :- डी – Neal

+0

कोई भी इस विचार के एक अद्यतन संस्करण के बारे में जानता है जिसे django 1.4 के लिए अद्यतन किया गया है? एक के लिए, बग (पिछले दो वर्षों में) तय कर दिया गया है, और उस मामले के लिए मुझे यकीन नहीं है कि साइटएडमिन स्कोप को यह पता होना चाहिए कि उपयोगकर्ता_प्रोफाइल का क्या अर्थ है। और वास्तव में, मैं वर्तमान में हो रही है त्रुटि अपवाद प्रकार: \t ImproperlyConfigured अपवाद मान: \t 'HospitalAdmin.fields' 'user_profiles' उस रूप में नहीं है जिसकी प्रति फ़ील्ड को दर्शाता है। बेशक, मॉडल नाम अलग हैं, लेकिन संरचना एक जैसी है। अस्पताल = साइट। –

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