If you have an object, “Status”, and you want to have a button from a template create a new Status instance automatically, can you just use the CreateView, but “skip” the form part?
In my setup, Status is related to a Client, and also to a Note. So, a Client has multiple Notes, and the Notes have multiple Statuses.
When I click the link/button for “Approve”, I can confirm the new Status instance is created, but I am still displaying the “generic_add.html” form to the user, which I don’t want to do. Ideally, I just want to create the new Status, then return back to the client record, and show a “success message” of “Note approved”.
I’m guessing there’s a way to do this without using the CreateView setup, but I also like having the “permissions_required” easily applied.
Thank you for any guidance you can offer!
models.py:
class Status():
client = models.ForeignKey(Client, on_delete=models.CASCADE)
note = models.ForeignKey(Note, on_delete=models.CASCADE)
approval_status = models.CharField(max_length=50, choices=ApprovalStatus.choices, default='')
comments = models.TextField(blank=True, default='')
views.py:
class StatusApprove(UserAccessMixin, SuccessMessageMixin, generic.CreateView):
permission_required = 'clients.add_status'
model = Status
form_class = StatusForm
template_name = 'generic_add.html'
success_message = model._meta.verbose_name + " added successfully."
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(StatusApprove, self).get_context_data(**kwargs)
# Grab the Client and Note passed in from urls.py
client_id = self.kwargs['client_id']
note_id = self.kwargs['note_id']
# Grab the Client and Note instance based on the ID passed in from urls.py
client = Client.objects.get(id=client_id)
note = Note.objects.get(id=note_id)
# Create a new Status instance of Approved
status = Status.objects.create(client=client, note=note, approval_status='Approved')
return context
def get_success_url(self):
return reverse('clients:detail', args=[str(self.kwargs['client_id'])])
urls.py:
path('<int:client_id>/status/<int:note_id>/approve', views.StatusApprove.as_view(), name="status_approve"),
forms.py:
class StatusForm(ModelForm):
class Meta:
model = Status
exclude = ['client', 'note']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset('',
'approval_status',
'comments',
),
Hidden('hidden_client_id', '{{ c_id }}'),
Hidden('hidden_note_id', '{{ note_id }}'),
ButtonHolder(
Submit('submit', 'Save'),
HTML("<a href='{{ view.get_success_url }}' class='btn btn-light'>Cancel</a>")
)
)
template.html:
<a href="{% url 'clients:status_approve' client.pk note.pk %}">Approve</a>