【问题标题】:Include other field as choices to foreign key, Django包括其他字段作为外键的选择,Django
【发布时间】:2017-10-09 22:19:38
【问题描述】:

我有两个模型如下:

class FlightSchedule(models.Model):
    tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
    flight_number = models.CharField(max_length=30, null=False, blank=False)
    flight_group_code = models.ForeignKey(FlightGroup, null=False, blank=False)
    origin_port_code = models.ForeignKey(Port, null=False, related_name="Origin", blank=False)
    destination_port_code = models.ForeignKey(Port, null=False, related_name="Destination", blank=False)
    flight_departure_time = models.TimeField()
    start_date = models.DateField()
    end_date = models.DateField()

    def __unicode__(self):
        return u'%s' % self.flight_number

    class Meta:
        verbose_name_plural = "flights Schedule"


class PosFlightSchedule(models.Model):
    tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
    pos_flight_number = models.ForeignKey(FlightSchedule, max_length=30, null=False, blank=False,
                                      related_name='pos_flight_number')
    pos_flight_departure_time = models.ForeignKey(FlightSchedule, max_length=30,
                                              related_name='pos_flight_departure_time')
    pos_route_id = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_route_id')
    pos_flight_date = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_flight_date')
    pax_count = models.IntegerField(null=True)

    def __unicode__(self):
        return u'%s' % self.pos_flight_number

    class Meta:
        verbose_name_plural = "Flights Schedule"

对于 pos_flight_departure_time ,我需要来自 FlightSchedule 类的 flight_departure_time 的选择。但是我在下拉列表中得到了flight_number 值。为了获得 flight_departure_time 值,我需要改变什么?这些类来自单个 django 项目中的不同应用程序。所以他们有两个管理文件。

【问题讨论】:

标签: python django django-models foreign-keys


【解决方案1】:

不,您实际上并不需要它。在第二个模型中,FlightScheduleDetail 只需要一个外键,FlightSchedule 只需要一个外键

class PosFlightSchedule(models.Model):
    tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
    flight = models.ForeignKey(FlightSchedule, null=False, blank=False,related_name='pos_flight_number')
                                              related_name='pos_flight_departure_time')
    pos_route_id = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_route_id')
            pax_count = models.IntegerField(null=True)

    def __unicode__(self):
        return u'%s' % self.pos_flight_number

    class Meta:
        verbose_name_plural = "Flights Schedule"

然后在第一个模型中声明的所有字段都自动对PosFlightSchedule可用

例如你可以这样做

p = PosFlightSchedule.objects.all()[0]
print (p.flight.flight_number)
print (p.flight.pos_flight_departure_time)

等等。

这是正确的做法。

【讨论】:

  • related_name='pos_flight_departure_time' 不是必需的吗?
  • 是的,那只是复制粘贴
  • 我从模型中删除了重复的字段。但我对航班号没有空约束
  • IntegrityError at /api/post_flight_schedule/ NOT NULL 约束失败:pos_data_posflightschedule.pos_flight_number_id
  • 这与本次讨论无关。您没有为必填字段传递值。
【解决方案2】:

您可以通过定义模型形式来解决这个问题,而不是更改为 models.py

class PosFlightScheduleForm(forms.ModelForm):
    pos_flight_departure_time = forms.ChoiceField(label="Pos Department Time",
                                   choices=[(i.pk, i.flight_departure_time) for i in FlightSchedule.objects.all()],
                                   required=True)


    def __init__(self, *args, **kwargs):
        super(PosFlightScheduleForm, self).__init__(*args, **kwargs)
        self.fields['pos_flight_departure_time'] = forms.ChoiceField(label="Pos Department Time",
                                   choices=[(i.pk, i.flight_departure_time) for i in FlightSchedule.objects.all()],
                                   required=False)


    class Meta:
        model = PosFlightSchedule
        fields = (
            "tail_number", 'pos_flight_departure_time',)

在 view.py 中你可以使用这个表单

def add_view(self, request):
    form = PosFlightScheduleForm(request.POST or None)

    if form.is_valid():
        form.save()                                    
        return redirect('/postflights')
    context = {
        'form': form,
    }
    return render(request, 'path/form.html', context)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 2016-08-01
    • 2019-11-20
    • 2018-12-13
    • 2020-11-13
    相关资源
    最近更新 更多