如何制作下拉菜单并将选择连接到CBGV

时间:2016-08-08 04:49:47

标签: python django django-templates django-views

我是Django的新手,并且正在努力了解如何在两个模型之间建立用户可访问的连接。

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

现在我想制作一个下拉菜单,其中包含可用研究组列表,并允许用户选择一个与PatientStatsView相关模板中的特定患者关联。如果研究组已经与患者实例相关联,则默认情况下需要在下拉列表中选择该研究组。

我不清楚实现此目的的最佳方法,并在患者模型中验证并保存选择。

最好在form.py中完成吗?

1 个答案:

答案 0 :(得分:0)

我认为最好的方法是通过forms.py来实现。特别是,您将改变数据库中的数据。由于这个原因,您可能希望将POST方法与CSRF一起使用。

首先,您需要使用a创建forms.py ModelChoiceField(我觉得它最适合你的任务),

  

允许选择适合表示外键的单个模型对象。

并在其上设置queryset参数。

  

模型对象的 QuerySet ,将从中导出字段的选项,并将用于验证用户的选择。

你可以这样做:

# forms.py
...
class PatientForm(forms.Form):
    studygroups = forms.ModelChoiceField(queryset=StudyGroup.objects.all(),
                                         label='Study groups')
    ...

然后,您可以通过POSTGET方法检查您的视图是否已请求该页面。如果用户第一次查看表单 - 通过GET方法,那么如果将用户分配给用户,则需要设置用户StudyGroup的默认值,否则返回{{1 }}。例如:

CBV:

None

CBGV:

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})

FBV:

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)

然后只需在html中呈现表单:

...
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})
...