2011-05-17 30 views
38

Standart bire-bir ilişki ayarlamam var. Orada alanların bir grup vardır, ama burada bizim için, ilgili modelidir: django admin ile bire çok sayıda satır içi seçim

class Class(models.Model): 
    name = models.CharField(max_length=128) 

class Student(models.Model): 
    class = models.ForeignKey(Class) 
    name = models.CharField(max_length=128) 
    address = models.CharField(max_length=128) 
    # ...etc 

Ben bir yöneticisi oluşturulur ve o inşaat büyük. Hatta bir Öğrenci'yi düzenlerken Sınıfı otomatik olarak ayarlama yeteneğim bile vardır. Ancak, bir Sınıfı oluşturmaya/düzenlemeye gittiğimde, tek alacağım isim için bir giriş kutusu.

Öğrenciler, Sınıf yöneticisi sayfasından Sınıf üyeleri olarak ekleyebileceğiniz bir kutu/alan eklemenin bir yolu var mı? Bir satır içi satır oluşturabilirim, ancak bu yeni Öğrenciler oluşturmaktır. Ben zaten tüm öğrencilerim oluşturdum ve sadece farklı sınıflara birden fazla mevcut öğrenci eklemek için hızlı bir yöntem arıyorum.

+0

Hiçbir şekilde. Çözümü çok devamlı bir şekilde sürdürdüğümden sonra bulamadım ... – zen11625

cevap

26

Burada önerilen Luke Sneeringer olarak "özel form" çözüm şudur: kısaca InlineModelAdmin(see InlineModelAdmin documentation here)

örnek kod istiyorum. Her neyse, bu (aslında doğal ve muhtemelen ortak) sorun için kutu dışı Django çözümü yokluğunda şaşırıyorum. Bir şey mi eksik?

from django import forms 
from django.db import models 
from django.contrib import admin 

class Foo(models.Model): 
    pass 

class Bar(models.Model): 
    foo = models.ForeignKey(Foo) 

class FooForm(forms.ModelForm): 
    class Meta: 
     model = Foo 

    bars = forms.ModelMultipleChoiceField(queryset=Bar.objects.all()) 

    def __init__(self, *args, **kwargs): 
     super(FooForm, self).__init__(*args, **kwargs) 
     if self.instance: 
      self.fields['bars'].initial = self.instance.bar_set.all() 

    def save(self, *args, **kwargs): 
     # FIXME: 'commit' argument is not handled 
     # TODO: Wrap reassignments into transaction 
     # NOTE: Previously assigned Foos are silently reset 
     instance = super(FooForm, self).save(commit=False) 
     self.fields['bars'].initial.update(foo=None) 
     self.cleaned_data['bars'].update(foo=instance) 
     return instance 

class FooAdmin(admin.ModelAdmin): 
    form = FooForm 
+1

Sonunda bunu çözmek için ne yaptığımı bilmiyorum. Oldukça buna benzer bir şey olduğu kesin. Ve evet, gerçekten garip bir şeyleri önceden/daha basit bir şeyleri yok. – MrGlass

+1

Bu çözümü beğendim, ancak "FIXME: 'commit' argümanı sıcak işlenir" ile ne demek istediğinden emin olmak istedim. Burada sorun nedir? –

+2

ModelForm API ile tutarlı olmak için, foo_form.save (commit = False), henüz veritabanına kaydedilmemiş bir nesne döndürmelidir (bkz. Https://docs.djangoproject.com/en/dev/topics/forms/ modelforms/#-save-yöntemi); hovewer sağlanan uygulama 'commit' argümanını yok sayar. Büyük olasılıkla commit = False kullanmayacaksınız; eğer öyleyse, sorun yok. – zag

29

Var!

class StudentAdminInline(admin.TabularInline): 
    model = Student 

class ClassAdmin(admin.ModelAdmin): 
    inlines = (StudentAdminInline,) 
admin.site.register(Class, ClassAdmin) 
+3

Bu arada, model sınıfınızı "Sınıf" olarak adlandırırken oldukça dikkatli olun. İşe yarayacak, ama daha sonra sizi ısıtacak (örneğin, 'Öğrenci' nin ilk satırında). Ve, class = models.ForeignKey (Class) '* * çalışmıyor, çünkü" class "ayrılmış bir kelimedir. –

+0

evet. Aslında, bunlar sahte isimler: P güvenlik, falan filan, vs. Daha sonra kötü ismin farkına vardı. Aslında, ödev yardımı arayan bir üniversite öğrencisi olarak çağrılmayı bekledim - bu bir hw ödevi için standart senaryo gibi. – MrGlass

+8

Denenmiş uygulama ve buna ihtiyacım var. Soruda söylediğim gibi, bir satır içi biçim eklemek nasıl biliyorum, ancak TabularInline yeni bir nesne oluşturmak için tasarlanmıştır. Kullanıcının halihazırda sahip olduğum mevcut öğrenci listesinden seçim yapmasına izin vermek istiyorum. – MrGlass