【问题标题】:Django forms: how to show only objects associated with user in dropdownDjango 表单:如何在下拉列表中仅显示与用户关联的对象
【发布时间】:2019-04-27 22:34:02
【问题描述】:

我是一家兽医医院,拥有宠物班和班级记录。每只宠物可以有许多记录,即每次去医院时都会获得一条新记录。

目前,我的表单显示了与我的应用关联的所有宠物(请查看https://i.stack.imgur.com/8j7V8.png)。

我只想显示用户注册的宠物(为什么 Bob 会带着陌生人的猫去看兽医?)

查看添加记录:

@login_required(login_url="/accounts/login/")
def record_create(request):
    #this line retrieves Pets only belonging to the user logged in
    pets = Pet.objects.filter(author=request.user)
    if request.method == 'POST':
        form = forms.CreateRecord(request.POST, request.FILES)
        print(form)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            instance.save()
            return redirect('records')
    else:
        form = forms.CreateRecord()
    return render(request, 'records/record_create.html', {'form': form,})

forms.py

class CreateRecord(forms.ModelForm):
    class Meta:
        model = models.Record
        fields = ['feedID', 'amountLeftOver', 'amountDispensed', 'additionalInfo', 'selectPet']

models.py

class Pet(models.Model):
    petName = models.CharField(max_length=100, default='My Pet')
    petImage = models.ImageField(default='default.png', blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)

    def __str__(self):
        return self.petName

class Record(models.Model):
    feedID = models.AutoField(primary_key=True)
    dateTime = models.DateTimeField(auto_now_add=True)
    amountLeftOver = models.IntegerField(default='0')
    amountDispensed = models.IntegerField(default='0')
    additionalInfo = models.TextField(default=" ")
    selectPet = models.ForeignKey(Pet, on_delete=models.CASCADE)
    author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)

如何让 selectPet 下拉菜单只显示 Bob 的注册宠物?

感谢您的宝贵时间!

【问题讨论】:

标签: django django-forms django-views django-shell


【解决方案1】:

您可以覆盖表单的__init__() 方法以传入额外的参数,在这种情况下,您可以传入一个用户实例,并为下拉小部件设置查询集。

(不确定您如何将 Pet 模型与 User 模型相关联,下面的示例假设您有一个外键)

class CreateRecord(forms.ModelForm):

    class Meta:
        model = models.record
        fields = ['feedID', 'amountLeftOver', 'amountDispensed', 'additionalInfo', 'selectPet']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        user = self.kwargs.get('user')
        if user:
            self.fields['selectPet'].queryset = user.pet_set.all()

【讨论】:

  • 小心更改表单的init方法的签名;如果视图没有在各处正确更新以发送给用户,则可能会导致问题。而是从kwargs 字典中获取用户。
【解决方案2】:

解决此问题的另一种方法

查看添加记录:

@login_required(login_url="/accounts/login/")

def record_create(request):

    #this line retrieves Pets only belonging to the user logged in
    pets = Pet.objects.filter(author=request.user)

    if request.method == 'POST':
        form = forms.CreateRecord(request.POST, request.FILES)
        print(form)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            instance.save()
            return redirect('records')
    else:
        form = forms.CreateRecord()                                              
        form.fields["category"].queryset=Record.objects.filter(user=request.user)
    return render(request, 'records/record_create.html', {'form': form,})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2020-07-25
    • 2021-06-14
    相关资源
    最近更新 更多