2009-10-15 10 views
6

Supongamos que estoy en la situación habitual, donde hay campos adicionales en la relación Many2Many:Trabajar con campos adicionales en un formulario en línea - save_model, save_formset, no puede dar sentido a la diferencia

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

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

# other models which are unrelated to the ones above.. 

class Trip(models.Model): 
    placeVisited = models.ForeignKey(Place) 
    visitor = models.ForeignKey(Person) 
pleasuretrip = models.Boolean() 

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

I desea agregar algunos campos adicionales en el formulario de membresía que se muestra a través del en línea. Estos campos son básicamente un acceso directo a la creación de instancias de otro modelo (Viaje). Trip puede tener sus propias vistas de administrador, pero estos accesos directos son necesarios porque cuando los socios de mi proyecto ingresan datos de 'Membresía' en el sistema, también tienen la información 'Viaje' a mano (y también porque parte de la información en Membresía puede ser copiado a Trip etc., etc.)

Así que todo lo que quiero es tener dos campos adicionales en la composición Inline - placeVisited y pleasuretrip - que junto con la instancia Persona me deja una instancia del modelo de viaje en el fondo ...

encontré Puedo agregar fácilmente campos adicionales a la vista en línea definiendo mi propio formulario. Pero una vez que se han ingresado los datos, ¿cómo y cuándo hacer referencia a ellos para realizar las operaciones de guardado que necesito hacer?

class MyForm(forms.ModelForm): 
place = forms.ModelChoiceField(required=False, queryset=Place.objects.all(), label="place",) 
pleasuretrip = forms.BooleanField(required=False, label="...") 

class MembershipInline(admin.TabularInline): 
model = Membership 
form = MyForm 
    def save_model(self, request, obj, form, change): 
     place = form.place 
     pleasuretrip = form.pleasuretrip 
     person = form.person 
     .... 
     # now I can create Trip instances with those data 
     .... 
     obj.save() 

class GroupAdmin(admin.ModelAdmin): 
model = Group 
.... 
inlines = (MembershipInline,) 

Esto no parece funcionar ... También estoy un poco desconcertado por el método save_formset ... a lo mejor es que el que debería usar? Muchos gracias de antemano por la ayuda !!!!

Respuesta

2

Acabo de resolver este problema, y ​​parece que la solución es que tanto para save_formset como save_model con inlines, no se llaman. En su lugar, debe implementarlo en el formset al que se llama, que es el principal, p.

model = Group 
    .... 
    inlines = (MembershipInline,) 

    def save_formset(self, request, form, formset, change): 
     instances = formset.save(commit=False) 

     for instance in instances: 
      # Here an instance is a MembershipInline formset NOT a group... 
      instance.someunsetfield = something 

      # I think you are creating new objects, so you could do it here. 
      instance.save() 
14

Como syn señala en su respuesta, por TabularInline y StackedInline, usted tiene que reemplazar el método save_formset dentro del ModelAdmin que contiene los inline.

GroupAdmin(admin.ModelAdmin): 
    model = Group 
    .... 
    inlines = (MembershipInline,) 

    def save_formset(self, request, form, formset, change): 
     instances = formset.save(commit=False) 

     for instance in instances: 
      if isinstance(instance, Member): #Check if it is the correct type of inline 
       if(not instance.author): 
        instance.author = request.user 
       else: 
        instance.modified_by = request.user    
       instance.save() 
Cuestiones relacionadas