简体   繁体   English

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

[英]How to make a drop down menu and connect the choice to a CBGV

I am new to Django and am struggling to understand how to make a user accessible connection between two models. 我是Django的新手,正在努力了解如何在两个模型之间建立用户可访问的连接。

models.py: 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: 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. 现在,我想创建一个包含可用研究组列表的下拉菜单,并允许用户在与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? 最好在form.py中完成吗?

The best way I see it can be done is via the forms.py , indeeed. 我认为可以做到的最好方法是通过forms.py ,确实。 Especially, that you will be altering the data in your database. 特别是,您将要更改数据库中的数据。 You would want to use POST method together with CSRF , because of that. 因此,您可能希望将POST方法与CSRF一起使用。

So you first of all you need to create forms.py with a ModelChoiceField (I find it most suitable for your task), which 因此,您首先需要使用ModelChoiceField (我发现它最适合您的任务)创建forms.py ,其中

Allows the selection of a single model object, suitable for representing a foreign key. 允许选择单个模型对象,适合于表示外键。

and set queryset parameter on it. 并在其上设置queryset参数。

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. 模型对象的QuerySet ,将从中推导出字段的选择,并将其用于验证用户的选择。

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. 然后,您将在视图中检查是否通过POSTGET方法请求了该页面。 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 . 如果用户第一次通过GET方法查看该表单,那么如果将用户分配给一个,则需要设置用户的StudyGroup的默认值,否则返回None For example: 例如:

CBV: CBV:

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

CBGV: CBGV:

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)

FBV: FBV:

...
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: 然后只需在您的html中呈现表单即可:

<form action="." method="post">
        {{ form.as_p}}
        {% csrf_token %}
        <p><input type="submit" value="Save"></p>
</form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM