Hello,
I’m using Class Based Views and trying to get a parent ID in the initial load of the form of a CreateView. I’ve looked through the documentation suggested in other posts (https://ccbv.co.uk/) and (Django Class Based Views Diagrams), but am still unsure of how to accomplish this.
It doesn’t matter if I even need to just use part of the URL to get the parent ID I’m looking for, I’m looking for any way to make this work.
I have a parent object, Client, which has an ID in the url, when creating a child, Note, object. Like this: http://127.0.0.1:8000/clients/1/note/add
In that case, the “1” is the Client ID that I want to get when the “Add Note” form is loading.
Here is the urls.py part of this:
path('<int:client_id>/note/add', views.NoteAdd.as_view(), name="note_add"),
Here is part of the forms.py code that is creating the multi-select field for the Note object. Essentially, I would like to filter the query set for the ‘goals’ field to only include Objective records for the parent Client ID of this object.
forms.py
class NoteForm(ModelForm):
class Meta:
model = Note
exclude = ['client']
widgets = {
'service_date': widgets.DateInput(attrs={'type': 'date'}),
'start_time': widgets.TimeInput(attrs={'type': 'time'}),
'end_time': widgets.TimeInput(attrs={'type': 'time'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
# Create multi-select checkboxes that only have the values for this specific client
self.fields['goals'] = ModelMultipleChoiceField(
#queryset=Objective.objects.filter(client=kwargs.get('instance').client.id),
queryset=Objective.objects.filter(client=self.kwargs['client_id']),
#queryset=Objective.objects.filter(client=client_id),
widget=CheckboxSelectMultiple
)
You can see the multiple (commented out) ways I’ve tried to access that “client_id” on the NoteForm when it first loads. This obviously works fine when editing a previously saved NoteForm, but not on the initial creation of a new Note.
Here is the Note object in models.py
class Note(TheBaseClass):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
service_date = models.DateField()
start_time = models.TimeField(blank=True, null=True)
end_time = models.TimeField(blank=True, null=True)
goals = models.ManyToManyField("Objective", verbose_name="Goals addressed")
I’m not sure if this helps, but here is part of the views.py file as well.
class NoteAdd(UserAccessMixin, SuccessMessageMixin, generic.CreateView):
permission_required = 'clients.add_note'
model = Note
form_class = NoteForm
template_name = 'generic_add.html'
success_message = model._meta.verbose_name + " added successfully."
The ultimate error message is:
# AttributeError at /clients/1/note/add
'NoteForm' object has no attribute 'kwargs'
This makes sense, because I suppose kwargs don’t exist yet at the time the form is being rendered, but I’m looking for a way to get that “client_id” from the URL and use that in the queryset filter.
Knowing all of this, how do I get the “client_id” (present in the url) to be used on NoteAdd load?