Domanda

Potrei essere completamente fuori dalla prenotazione qui. (Sentiti libero di dirmi se lo sono.)

Il mio caso d'uso è che ho un elenco di scuole. Il modello scolastico è piuttosto semplice:

class School(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)

Quando il mio utente vuole modificare una di queste scuole, non voglio che modifichi la copia principale. Invece, voglio dare loro la propria copia con cui possono giocare. Quando hanno finito di modificare la loro copia, possono inviare il loro cambiamento e qualcun altro lo approverà. Quindi ho un'altra classe per la copia dell'utente della scuola:

class UserSchool(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)
    master_school = models.ForeignKey(School)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

Quindi ho impostato un modulo per gestire l'editing della scuola di utenti:

class UserSchoolForm(forms.ModelForm):
    class Meta:
        model = UserSchool
        fields = ['name','mascot']

E ora ho la mia forma di edizione:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get(self, request, *args, **kwargs):
        school = self.get_object()

        # make a copy of the school for this user
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})

        self.object = user_school
        form = UserSchoolForm()
        context = self.get_context_data(form=form)
        return self.render_to_response(context)

So che get () sta realizzando correttamente la copia, ma quando il modulo viene visualizzato, non ci sono valori elencati nei campi "nome" o "predefiniti". Il mio sospetto è che il problema è con il fatto che Cls.Model = School, ma self.object è un'istanza di utenti.

Sono vicino ma mi manca qualcosa? Sono completamente sulla strada sbagliata? Esiste un modello migliore per questo (come avere una singola istanza di scuola con un utente speciale per "Master")?

(E una piccola complicazione-Dato che sono una vecchia mano a Django, ma nuove viste basate sulla classe, sto cercando di usare viste alla vaniglia perché trovo più facile capire cosa sta succedendo.)

È stato utile?

Soluzione

Solo per escludere l'ovvio - non stai passando nulla al costruttore di forma. L'hai provato con instance=user_school? Potrebbe esserci più che ha bisogno di lavoro ma inizierei da lì.

Per espandersi un po 'su questo - a tuo avviso, stai preparando completamente l'intero get metodo. Va bene, ma significa che stai aggirando parte del comportamento automatizzato della tua superclasse. In particolare, il get metodo di ProcessFormView (una delle tue classi antenati) istanzia il modulo usando il get_form Metodo della classe Visualizza. FormMixin, un altro antenato, definisce get_form:

return form_class(**self.get_form_kwargs())

E get_form_kwargs Su ModelFormMixin aggiunge self.object al modulo kwargs:

kwargs.update({'instance': self.object})

Perché il tuo sovraccarico get Il metodo non chiama get_form, inoltre non chiama get_form_kwargs E quindi non attraversa l'intero percorso che fornisce un legame iniziale per la forma.

Personalmente proverei a gestirlo modificando il get_object Metodo della tua vista personalizzata e lasciare il resto da solo:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get_object(self, queryset=None):
        school = super(EditSchool, self).get_object(queryset=queryset)
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=self.request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})
        return user_school

Potrebbero esserci più modifiche necessarie - non l'ho testato - ma sia il get e set metodi usa get_object, e legalo alla forma come appropriato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top