I am new to Django and am struggling to understand how to make a user accessible connection between two models.
models.py:
class StudyGroup(models.Model):
start_date = models.DateTimeField()
end_date = models.DateTimeField()
ex_1_trial = models.IntegerField(blank=True, null=True, default=None)
ex_2_trial = models.IntegerField(blank=True, null=True, default=None)
...
def __str__(self):
return self.studygroup_name
class Patient(models.Model):
type = models.CharField('Type', max_length=20, db_index=True, help_text='s', primary_key=True)
patient_name = models.CharField('Name', max_length=200, db_index=True, help_text='n')
studygroup = models.ForeignKey(StudyGroup, verbose_name='StudyGroup')
...
def __str__(self):
return self.patient_name
views.py:
class SidebarList(object):
def get_context_data(self, **kwargs):
context = super(SidebarList, self).get_context_data(**kwargs)
context['my_patient_list'] = Patient.objects.order_by('company_name')
return context
class PatientStatsView(SidebarList, DetailView):
model = Patient
template_name = 'screener/patient_stats.html'
def get_context_data(self, **kwargs):
context = super(CompanyStatsView, self).get_context_data(**kwargs)
... some sorting and stuff here ...
context['blah'] = some_values
return context
Now I want to make a drop down menu with the list of available studygroups in it and allow the user to select one to associate with a particular patient in the template associated with PatientStatsView. If a studygroup is already associated with a the patient instance, then that studygroup needs to be selected by default in the drop down.
I am unclear about the best ways to achieve this and to have the selection verified and saved in the patient model.
Is this best done in the form.py?
The best way I see it can be done is via the forms.py
, indeeed. Especially, that you will be altering the data in your database. You would want to use POST
method together with CSRF
, because of that.
So you first of all you need to create forms.py
with a ModelChoiceField
(I find it most suitable for your task), which
Allows the selection of a single model object, suitable for representing a foreign key.
and set queryset
parameter on it.
A QuerySet of model objects from which the choices for the field will be derived, and which will be used to validate the user's selection.
You could do it for example like this:
# forms.py
...
class PatientForm(forms.Form):
studygroups = forms.ModelChoiceField(queryset=StudyGroup.objects.all(),
label='Study groups')
...
Then you would check in your view if the page was requested via POST
or GET
method. If user views the form for the first time - via GET
method, then you would want to set the default value of user's StudyGroup
if user is assigned to one, else return None
. For example:
class HomeView(View):
form_class = PatientForm
template_name = 'home.html'
def get(self, request, *args, **kwargs):
initial = {'studygroups': request.user.patient.studygroup.pk}
form = self.form_class(initial=initial)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
...
return HttpResponseRedirect('/success/')
return render(request, self.template_name, {'form': form})
class HomeView(FormView):
form_class = PatientForm
template_name = 'home.html'
success_url = '/success/'
def get_initial(self):
initial = super(HomeView, self).get_initial()
initial['studygroups'] = self.request.user.patient.studygroup.pk
return initial
def form_valid(self, form, *args, **kwargs):
return super(HomeView, self).form_valid(form)
...
if request.method == 'POST':
form = PatientForm(data=request.POST)
if form.is_valid():
...
form.save()
else:
# some logic which would assign the patient studygroup's pk
# to default_group_pk variable.
# or None if no default group should be selected
# i.e. user is not logged in or is not assigned to any studygroup.
# You could get logged in Patient's studygroup via:
# default_group_pk = request.user.patient.studygroup.pk
form = PatientForm(initial={'studygroups': default_group_pk})
...
Then simply render the form in your html:
<form action="." method="post">
{{ form.as_p}}
{% csrf_token %}
<p><input type="submit" value="Save"></p>
</form>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.