Django CreateView: Comment faire pour effectuer une action sur enregistrer
Je suis en utilisant une mesure CreateView (CourseCreate) et UpdateView (CourseUpdate) la sauvegarde et la mise à jour d'un Cours. Je veux prendre une action lorsque le Cours est enregistré. Je vais créer une nouvelle plusieurs-à-plusieurs relation entre le formateur des nouveaux cours et de l'utilisateur (si elle n'existe pas déjà).
Donc, je veux sauver le Cours comme cours, et ensuite utiliser bien sûr.faculté de créer cette nouvelle relation. Où est le meilleur endroit pour ce faire?
Je suis en train de le faire dans form_valid dans les points de vue, mais j'ai des erreurs lorsque vous essayez d'accéder à un formulaire.exemple.faculté bc le parcours n'est pas encore créé (dans CourseCreate). Le message d'erreur est semblable:
"Cours: ..." doit avoir une valeur pour le champ "cours" avant cela, plusieurs-à-plusieurs relations peuvent être utilisés.
C'est aussi ne fonctionne pas dans CourseUpdate. L'Aide de la relation n'est pas créé. Devrais-je essayer ce dans le Formulaire? Mais je ne suis pas sûr de savoir comment obtenir les infos de l'utilisateur vers le Formulaire.
Merci.
models.py
class Faculty(models.Model):
last_name = models.CharField(max_length=20)
class Course(models.Model):
class_title = models.CharField(max_length=120)
faculty = models.ManyToManyField(Faculty)
class UserProfile(models.Model):
user = models.OneToOneField(User)
faculty = models.ManyToManyField(Faculty, through='Assists')
class Assists(models.Model):
user = models.ForeignKey(UserProfile)
faculty = models.ForeignKey(Faculty)
views.py
class CourseCreate(CreateView):
model = Course
template_name = 'mcadb/course_form.html'
form_class = CourseForm
def form_valid(self, form):
my_course = form.instance
for f in my_course.faculty.all():
a, created = Assists.objects.get_or_create(user=self.request.user.userprofile, faculty=f)
return super(CourseCreate, self).form_valid(form)
class CourseUpdate(UpdateView):
model = Course
form_class = CourseForm
def form_valid(self, form):
my_course = form.instance
for f in my_course.faculty.all():
a, created = Assists.objects.get_or_create(user=self.request.user.userprofile, faculty=f)
return super(CourseUpdate, self).form_valid(form)
- Essayez de remplacer
my_course = form.instance
avecmy_course = form.save(commit=False)
- je vous remercie. Lorsque j'essaie que, après avoir cliqué sur Enregistrer btn lors de la création d'un nouveau cours, je vois toujours le même message d'erreur:" Le Parcours de l'objet doit avoir une valeur pour le champ "cours" avant cela, plusieurs-à-plusieurs relations peuvent être utilisés." Je n'arrive pas à comprendre d'où le "cours" de mentionner vient de... j'ai une classe nommée Sûr, mais il n'a pas un champ nommé "cours", et mon avis n'a aucune mention d'un "cours".
Vous devez vous connecter pour publier un commentaire.
La
form_valid()
méthode pourCreateView
etUpdateView
enregistre le formulaire, puis redirige vers la réussite de l'url. Il n'est pas possible de fairereturn super()
, parce que vous voulez faire des trucs entre l'objet de la sauvegarde et de la redirection.La première option est de ne pas appeler
super()
, et copier les deux lignes dans votre point de vue. L'avantage de cela est qu'il est très clair ce qui se passe.La deuxième option est de continuer à appeler
super()
, mais ne renvoie pas la réponse jusqu'à ce que après avoir mis à jour la relation. L'avantage, c'est que vous n'êtes pas dupliquer le code danssuper()
, mais l'inconvénient est qu'il n'est pas clair ce qu'il se passe, sauf si vous êtes familier avec ce quesuper()
n'.form_valid()
et la mise à jourform.instance
qui est généré à l'aide de données de POSTES, comme le résultat deform.is_valid
appelé juste avant deform_valid()
. Cetteinstance
est ensuite utilisée pour définirobject
quandform.save()
est appelé dansform_valid
form.instance
estNone
pourCreateView
. Vous pouvez définirinstance
àCourse()
dansget_form_kwargs
, mais ce n'est pas beaucoup vous aider pour cette question en particulier, parce que l'instance doit être enregistré avant de pouvoir définir les valeurs de la plusieurs-à-plusieurs domaine.Je suggère d'utiliser Django du Signal. C'est une action qui se déclenche quand quelque chose arrive à un Modèle, comme enregistrer ou mise à jour. De cette façon, votre code reste propre (pas de logique métier dans le formulaire de manutention), et de vous assurer qu'il ne se déclenche après enregistrer.
faculty
à l'aide de lapost_save
signal, voir cette réponse stackoverflow.com/a/23796604/263989