首页 > 解决方案 > django中的交叉查询

问题描述

我有两个模型如下

class Watched(Stamping):
    user = models.ForeignKey("User", null=True, blank=True, on_delete=models.CASCADE,
                             default=None)
    count = models.PositiveIntegerField()


class Link(Stamping):
    ...
    user = models.ForeignKey(User,  on_delete=models.CASCADE, default=None)
    url = models.CharField(max_length=256, default=None)
    watched = models.ForeignKey(Watched, null=True, blank=True, on_delete=models.CASCADE, default=None)
    ...

我的表格.py

class SimpleLink(forms.Form):
    url = forms.URLField(max_length=256)

用户可以创建一个Link对象,当满足某些条件时,该对象将被添加到Watched. 该Watched模型包含由不同用户创建的对象。现在我想过滤Watched类并只获取模型中请求用户创建的对象,Link但我不知道如何实现。任何帮助将不胜感激。我想要实现的一个示例是 Watched.objects.filter(Link.objects.filter(user=request.user)...... 我知道我的样本很疯狂。但是从外部查询中,我想获取用户发出请求时创建的 Link 对象

标签: djangodjango-models

解决方案


您需要限制ModelForm. 因此, AModelForm将如下所示:

from django import forms

class LinkForm(forms.ModelForm):
    
    def __init__(self, *args, user=None, **kwargs):
        super().__init__(*args, **kwargs)
        if user is not None:
            self.fields['watched'].queryset = Watched.objects.filter(
                link__user=user
            )

    class Meta:
        model = Link
        fields = ['url', 'watched']

在我们看来,我们可以设置user对象:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render

@login_required
def some_view(request):
    if request.method == 'POST':
        form = LinkForm(request.POST, user=request.user)
        if form.is_valid():
            form.instance.user = request.user
            form.save()
            return redirect('name-of-some-form')
    else:
        form = LinkForm(user=request.user)
    return render(request, 'some-template.html', {'form': form})

对于基于类的视图,我们可以覆盖.get_form_kwargs(…)方法 [Djangod-doc]

from django.contrib.auth.mixins import LoginRequiredMixin

class SomeView(LoginRequiredMixin, CreateView):
    form_class = LinkForm
    
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

推荐阅读