【问题标题】:Django ModelChoiceField: filtering object based on pk in urlDjango ModelChoiceField:基于 url 中的 pk 过滤对象
【发布时间】:2021-07-04 11:02:59
【问题描述】:

我已经阅读了很多关于这个主题的问题,但没有一种方法适合我。

有3个相关模型:

class Trips(models.Model):
    lake = models.CharField("Lake", max_length=150)
    city = models.CharField("City", max_length=100, blank=True)
    s_date = models.DateTimeField("Starting Date", auto_now=False, auto_now_add=False)
    e_date = models.DateTimeField("Ending Date", auto_now=False, auto_now_add=False)
    trip_id = models.AutoField(primary_key=True)    

    class Meta:
        verbose_name = "Trip"
        verbose_name_plural = "Trips"

    def __str__(self):
        return f"{self.lake}-{self.trip_id}-{self.s_date}"

class Fisherman(models.Model):
    name = models.CharField("Fisherman", max_length=50)
    trip = models.ForeignKey(Trips, on_delete=models.CASCADE)
    fisherman_id = models.AutoField(primary_key=True)

    class Meta:
        verbose_name = "Fisherman"
        verbose_name_plural = "Fishermen"

    def __str__(self):
        return f"{self.name}-{self.fisherman_id}"


class Catch(models.Model):
    fish_type = models.CharField("Fish Type", max_length=50)
    catch_id = models.AutoField(primary_key=True)
    weight = models.DecimalField("Weight", max_digits=5, decimal_places=2)
    length = models.DecimalField("Length", max_digits=5, decimal_places=2, blank=True, null=True)
    datetime = models.DateTimeField("Catch Time", auto_now=False, auto_now_add=False)
    fisherman = models.ForeignKey(Fisherman, on_delete=models.CASCADE)
    trip = models.ForeignKey(Trips, on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Catch"
        verbose_name_plural = "Catches"

    def __str__(self):
        return f"{self.fish_type}-{self.catch_id}"

我有一个 ModelForm 来创建一个新的捕获。在这里,我使用 ModelChoiceField 列出渔民,但我不知道如何过滤它们。我只想显示那些属于旅行的人。

class CatchForm(forms.ModelForm):
    fisherman = forms.ModelChoiceField(queryset= Fisherman.objects.all())
    class Meta:
        model = Catch
        fields = ["fish_type", "weight", "length", "datetime", "fisherman"]
        widgets = {
            "datetime": forms.DateTimeInput(format='%Y-%m-%d %H:%M', attrs={'class':'datetimefield form-control'}),
        }

views.py

我读过 get_form_kwargs 应该在视图中用于覆盖表单中的字段,但它对我不起作用。

class NewCatchView(CreateView):
    model = Catch
    form_class = CatchForm
    template_name = "new_trip/new_catch.html"
    
    # Probably, this is wrong
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['fisherman'] = Fisherman.objects.filter(trip=self.kwargs.get('pk'))
        return kwargs
    
    def form_valid(self, form):
        form.instance.trip = Trips.objects.get(pk=self.kwargs['pk'])
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('new_trip:trip_details', args=(self.kwargs['pk'],))

urls.py

path("trip_details/<int:pk>/new_catch/", views.NewCatchView.as_view(), name="new_catch"),

提前感谢您的帮助!

【问题讨论】:

    标签: django django-views django-forms django-class-based-views django-generic-views


    【解决方案1】:

    你快到了。您已经创建了 kwarg,所以现在您只需在表单中使用它来覆盖原始查询集:

    class CatchForm(forms.ModelForm):
        ...
    
        def __init__(self, *args, **kwargs):
            fisherman = kwargs.pop('fisherman')
            super().__init__(*args, **kwargs)
            self.fields['fisherman'].queryset = fisherman
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-15
      • 2014-01-31
      • 2019-12-23
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 2016-08-13
      相关资源
      最近更新 更多