首页 > 解决方案 > Django 表单下拉字段显示其他用户拥有的数据

问题描述

我无法从 CreateView 和 Form 中仅查询用户拥有的项目:

# views.py
class ExpenseCreateView(LoginRequiredMixin, CreateView):
    model = Expense
    form_class = ExpenseCreateForm
    template_name = "expenses/expense_form.html"
    success_url = reverse_lazy("expense-list")

    def form_valid(self, form):
        form.instance.owner = self.request.user
        return super(ExpenseCreateView, self).form_valid(form)
# forms.py
class ExpenseCreateForm(forms.ModelForm):
    class Meta:
        model = Expense
        exclude = ("owner", )
        widgets = {"date": DateInput(), "time": TimeInput()}
# models.py
class Expense(models.Model):
    date = models.DateField(db_index=True)
    time = models.TimeField(null=True, blank=True)
    amount = models.DecimalField(max_digits=10, decimal_places=2, help_text="Amount of € spent.")
    location = models.ForeignKey("Location", on_delete=models.SET_NULL, null=True)
    document = models.FileField(
        upload_to=UploadToPathAndRename("documents/"), blank=True, null=True
    )
    image = models.ImageField(
        upload_to=UploadToPathAndRename("images/"), blank=True, null=True
    )
    payment = models.ForeignKey("Payment", on_delete=models.SET_NULL, db_index=True, null=True)
    comment = models.TextField(null=True, blank=True, help_text="Additional notes...")
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

class Payment(models.Model):
    title = models.CharField(max_length=100)
    comment = models.TextField(blank=True, null=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

该表单有效,但每个用户都可以看到其他用户的位置和付款。哪个是添加验证/检查以仅返回由用户发出请求所拥有的位置的正确位置和方法?

标签: pythondjangodjango-modelsdjango-viewsdjango-forms

解决方案


我通常将用户作为参数传递给表单以设置查询集以限制选择。

class ExpenseCreateView(LoginRequiredMixin, CreateView):
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["user"] = self.request.user
        return kwargs

class ExpenseCreateForm(forms.ModelForm):
    def __init__(self, *args, user, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.fields['location'].queryset = user.location_set.all()
        self.fields['payment'].queryset = user.payment_set.all()

推荐阅读