2013-09-03 13 views
7

Robię aplikację Django z niestandardowymi użytkownikami. Poniżej przedstawiłem kluczowe elementy mojego problemu, brakujący kod oznaczono "...". Mój model niestandardowy użytkownik ma relacji klucza obcego w następujący sposób:Django ModelChoiceField nie ma przycisku plusa

class MyCustomUser(models.AbstractBaseUser, models.PermissionsMixin) 
    ... 
    location = models.ForeignKey(Location) 

class Location(models.Model) 
    name = models.CharField(max_length=50, blank=True, null=True) 

Pisałem niestandardową formę obsługi, która zawiera tego pola w następujący sposób:

class MyCustomUserCreationForm(models.ModelForm) 
    ... 
    location = forms.ModelChoiceField(Location.objects.all()) 

To wszystko wydaje się działać poprawnie, jednak , nie ma przycisku plus po prawej stronie pola wyboru lokalizacji. Chcę móc dodać lokalizację, gdy utworzę użytkownika, w taki sam sposób, w jaki można dodawać ankiety podczas tworzenia opcji w pliku Django tutorial. Według to this question, mogę nie widzieć zielonego plusa, jeśli nie mam uprawnień do zmiany modelu, ale jestem zalogowany jako superuser z wszystkimi uprawnieniami. Masz pojęcie, co robię źle?

Odpowiedz

11

Musisz ustawić RelatedFieldWidgetWrapper opakowanie w formularzu Model:

RelatedFieldWidgetWrapper (znaleziono w django.contrib.admin.widgets) jest stosowany na stronach administratorowi obejmują zdolność na klucz obcy kontrola, aby dodać nowy powiązany rekord. (W języku angielskim: stawia mały zielony znak plus po prawej kontrolą.)

class MyCustomUserCreationForm(models.ModelForm) 
    ... 
    location = forms.ModelChoiceField(queryset=Location.objects.all()) 

    def __init__(self, *args, **kwargs): 
     super(MyCustomUserCreationForm, self).__init__(*args, **kwargs) 
     rel = ManyToOneRel(self.instance.location.model, 'id') 
     self.fields['location'].widget = RelatedFieldWidgetWrapper(self.fields['location'].widget, rel, self.admin_site) 

mogłem popełnić błąd w kodzie przykładowym, więc zobaczyć te posty i przykłady:

+1

Wskazałaś mi właściwy kierunek, dzięki za wszystkie linki. Użyłem twojego kodu, ale musiałem go trochę zmodyfikować. Musiałem dodać kilka linii do ModelAdmin, aby przekazać stronę administratora do formularza i zdefiniować rel jako 'MyCustomUser._meta.get_fields ('location'). Rel' – EmeraldOwl

+2

@EmeraldOwl: Minor Typo -' MyCustomUser. _meta.get_field ("location"). rel'. – Shubham

2

Google wskazał mi na tej stronie, szukając jak uzyskać ikonę „+” obok pola w formularzu niestandardowym z ForeignKey relacji, więc pomyślałam, że dodam.

U mnie, używając django-autocomplete-light, udało się bardzo dobrze, używając funkcji "dodaj kolejny".

+0

Twój link jest uszkodzony. –

6

Stworzyłem metoda oparta na powyższych odpowiedzi:

def add_related_field_wrapper(form, col_name): 
    rel_model = form.Meta.model 
    rel = rel_model._meta.get_field(col_name).rel 
    form.fields[col_name].widget = 
    RelatedFieldWidgetWrapper(form.fields[col_name].widget, rel, 
    admin.site, can_add_related=True, can_change_related=True) 

A potem wywołanie tej metody z mojego formularza:

class FeatureForm(forms.ModelForm): 
    offer = forms.ModelChoiceField(queryset=Offer.objects.all(), required=False) 
    package = forms.ModelChoiceField(queryset=Package.objects.all(), required=False) 
    def __init__(self, *args, **kwargs): 
     super(FeatureForm, self).__init__(*args, **kwargs) 
     add_related_field_wrapper(self, 'offer') 
     add_related_field_wrapper(self, 'package') 

To działa dobrze na Django 1.8.2.

+0

Muszę dodać 'class Meta \ n \ tmodel = ModeName \ n \ tfields = ('offer', 'package')' – luzik

Powiązane problemy