Django 3 - 使模型的 FK 下拉列表仅显示当前用户的数据

Posted

技术标签:

【中文标题】Django 3 - 使模型的 FK 下拉列表仅显示当前用户的数据【英文标题】:Django 3 - Making Model's FK Dropdown Display Current User's Data Only 【发布时间】:2020-05-23 01:06:26 【问题描述】:

我正在使用 Django 创建我的第一个应用程序,还有很多东西要学,但现在我完全陷入困境,需要一些帮助。我有一个客户和票的模型。我有它,所以不同的用户可以保存新客户/票证,并且只有在登录后才能从仪表板查看他们的数据。但是,在创建新票证时,有一个下拉选项可以为票证选择客户 - 当前用户能够看到每一位用户的客户。

这是代码,如果需要,我会分享更多代码,但我认为这涵盖了我正在做的事情......

forms.py

class TicketForm(ModelForm):
    class Meta:
        model = Ticket
        fields = ['number', 'customer','date_created','work_description','mechanics','status']

views.py

def createTickets(request):
    form = TicketForm()
    if request.method == 'POST':
        form = TicketForm(request.POST)
        if form.is_valid():
            newticket = form.save(commit=False)
            newticket.shopowner = request.user
            newticket.save()
            return redirect('tickets')
    context = 
        'form': form
    
    return render(request, 'createticket.html', context)

models.py

class Ticket(models.Model):
    def default_number():
        no = Ticket.objects.count()
        return no + 1
    shopowner = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
    number = models.CharField(max_length=30, unique=True, default= default_number)
    customer = models.ForeignKey(Customer, default=1, on_delete= models.SET_DEFAULT, blank=True)
    date_created = models.DateField(default=timezone.now)
    work_description = models.TextField(verbose_name="Service Details: ")
    mechanics = models.ForeignKey(Mechanic, default=1, on_delete=models.DO_NOTHING, blank=True, verbose_name="Mechanic")
    status = models.BooleanField(default=True, verbose_name="Open Ticket")
    class Meta:
        verbose_name_plural = "Tickets"

我需要 Customer 外键来仅显示当前用户(或“店主”)的客户 - 机械师和最终车辆也是如此,但一旦我知道如何获取客户输入以显示正确的数据,我就可以弄清楚这些.

【问题讨论】:

【参考方案1】:

您需要稍微自定义表单,以便修改该特定字段的查询集。我们还需要从视图中传递一个用户:

forms.py

class TicketForm(ModelForm):
    class Meta:
        model = Ticket
        fields = ['number', 'customer', 'date_created', 'work_description', 'mechanics', 'status']

    def __init__(self, user=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if user:
            self.fields['customer'].queryset = Customer.objects.filter(shopowner=user)

views.py

def createTickets(request):
    form = TicketForm(user=request.user)
    # ...

您如何定义查询集将取决于您如何定义CustomerShopowner 之间的关系,但这应该为您提供正确的方法。

【讨论】:

我收到“TicketForm' 对象没有属性 'request'” 错误.. 会玩一段时间因为我在别处读过的内容,这似乎是要走的路。谢谢!一旦我得到它,我会将其标记为已接受的答案并分享我必须做的事情。 啊抱歉 - 这样做是出于我的考虑。您需要明确地将用户传递给表单。我更新了我的答案。 有效!!谢谢格雷格,你不知道我有多感激!我想我应该对刚刚发生的事情做更多的了解,这样我才能更好地理解它。但是,我很高兴它现在可以工作了!

以上是关于Django 3 - 使模型的 FK 下拉列表仅显示当前用户的数据的主要内容,如果未能解决你的问题,请参考以下文章

Django:是否可以通过模型的PK将模型的FK链接到一对多关系?

django表单存储模型的下拉列表

Django模型中的下拉列表

Django admin:从反向 FK 聚合中排序 list_display 字段

来自数据库的 Django 动态下拉列表

获取模型对象的 id,它是另一个模型对象 django 的 FK