如何将主键从一个模型传递到另一个模型,并在模板中显示第一个模型的某些字段?

时间:2019-08-21 05:43:24

标签: django django-models django-templates django-views

我有2个模型,“候选”和“跟踪器”。 如果愿意,我想将候选者添加到跟踪器列表中。跟踪器还有一些其他字段。但是,在跟踪器模板中,我希望显示候选人的一些详细信息,例如姓名,电话等。 基本上,跟踪器页面包含添加的候选项以及有关它们的一些额外详细信息。

候选模型.py

class Candidate(models.Model):
    candidate_name = models.CharField(max_length=100)
    phone = models.CharField(max_length=100)
    email = models.EmailField()
    current_company = models.CharField(max_length=100)
    current_designation = models.CharField(max_length=100)

    def __str__(self):
        return self.candidate_name

    def get_absolute_url(self):
        return reverse('candidate-detail', kwargs={'pk': self.pk})

Tracker models.py

class Tracker(models.Model):
    candidate_name = models.ForeignKey(Candidate, on_delete=models.CASCADE, 
    related_name='candidates')
    position_applied = models.CharField(max_length=100)
    current_CTC = models.CharField(max_length=100)
    expected_CTC = models.CharField(max_length=100)

    def __str__(self):
        return self.position_applied

    def get_absolute_url(self):
        return reverse('tracker-detail', kwargs={'pk': self.pk})

views.py文件..

class TrackerCreateView(LoginRequiredMixin, CreateView):
    model = Tracker
    fields = ['current_CTC', 'expected_CTC', 'position_applied', 'candidate_name']

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)
class CandidateCreateView(LoginRequiredMixin, CreateView):
    model = Candidate
    fields = ['candidate_name', 'phone', 'email','current_company', 
    'current_designation']

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

直到现在,我刚刚将候选人作为外键。但这需要从下拉列表中选择候选名称,这不切实际。 如何在跟踪器列表中显示姓名,电话,电子邮件等?

我在候选页面的每个名称上都有一个'添加到跟踪器'按钮,该按钮会打开Tracker CreateView表单,让我填写并提交详细信息。有什么方法可以自动填充与一些肠子形成? 还是我可以采用其他方法?也许通过主键之类的?在urls.py文件中要进行哪些更改?

1 个答案:

答案 0 :(得分:0)

问题1 :如何自定义下拉菜单的显示以选择Candidate

您需要覆盖candidate_name使用的实际表单字段。默认情况下,这是一个ModelChoiceField,它具有方法label_from_instance(),您可以重写该方法来决定要显示的内容(而不仅仅是名称):

  1. 子类ModelChoiceField并仅覆盖label_from_instance()
  2. 子类ModelForm仅覆盖candidate_name字段,如here所述
  3. 将此类作为form_class添加到您的CreateView

问题2 :如何预填充TrackerCreateView

Here是有关Django通用CBV的非常有用的参考。您将看到CreateView有一个get_initial()方法,可用于使用初始值填充表单(只需将其传递给包含值的字典)即可。对您的CreateView的第一个请求是GET请求,因此您只需要传递URL查询参数即可为视图提供一些其他信息。因此,在您的情况下:

  1. 将查询参数添加到调用TrackerCreateView的URL中,例如在按钮模板中:

    <a href="{% url 'tracker-create' %}?candidate_id={{ candidate.id }}">
    
  2. 覆盖get_initial()中的TrackerCreateView方法。 self.request.GET将是包含您的URL查询参数的字典:

    def get_initial(self):
        initial = super().get_initial()
        candidate_id = self.request.GET.get('candidate_id')
        if candidate_id:
            try:
                candidate = Candidate.objects.get(id=candidate_id)
            except Candidate.DoesNotExist:
                pass
            else:
                initial.update({'candidate_name': candidate})
        return initial
    
  3. 现在,您的表单将被候选者预填充。