I have 2 models, Message and Attachment. I want to use these in one form. The Attachment should have a reference to the message (a message can have more than 1 attachment).
Models:
class Message(models.Model):
createdby = models.ForeignKey(User)
subject = models.CharField(max_length=200, null=True)
body = models.TextField(default=None, blank=True)
class Attachment(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
message = models.ForeignKey(Message, null=True)
Forms
class MessageForm(forms.ModelForm):
class Meta:
model = Message
AttachmentFormSet = inlineformset_factory(Message, Attachment, extra=1 )
Views
class MessageCreateView(CreateView):
model = Message
fields = ["subject", "body"]
form_class = MessageForm
success_url = 'success/'
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
attachment_form = AttachmentFormSet()
return self.render_to_response(
self.get_context_data(form =form,
attachment_form=attachment_form,
))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
attachment_form = AttachmentFormSet(self.request.POST)
if (form.is_valid() and attachment_form.is_valid()):
return self.form_valid(form, attachment_form)
else:
return self.form_invalid(form, attachment_form)
def form_valid(self, form, attachment_form):
"""
Called if all forms are valid. Creates a Message instance along with
associated Attachment then redirects to a success page.
"""
self.object = form.save()
attachment_form.instance = self.object
self.object = attachment_form.save()
return HttpResponseRedirect(self.get_success_url())
I tried many things, but for some reason the Attachment is never saved. There must be something missing in the form_valid() function, but I can't figure out what.
For completeness, here also the template:
<script type="text/javascript">
$(function() {
$(".inline.{{ attachment_form.prefix }}").formset({
prefix: "{{ attachment_form.prefix }}"
})
});
</script>
<form class="" action="/bugtrack/project/{{ project_id }}/tickets/{{ ticket_id }}/replyform/" method="post" id="replyform">
{% csrf_token %}
{{ form |crispy }}
{{ attachment_form.management_form }}
{% for formattach in attachment_form %}
{{ formattach.id }}
<div class="inline {{ attachment_form.prefix }}">
{{ formattach.docfile }}
</div>
{% endfor %}
<button class="btn btn-info pull-right btn-sm" type="submit" name="submit" value="createReply">Submit</button>
</form>
What would be the correct way to save the Message and Attachment correctly using a formset?
Aucun commentaire:
Enregistrer un commentaire