#django #django-models
Вопрос:
У меня есть две модели, как показано ниже
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)
...
Мой forms.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)
. Я знаю, что мой образец сумасшедший. Но из внешнего запроса я хочу захватить объекты ссылок, созданные пользователем, отправившим запрос
Комментарии:
1. Можете ли вы поделиться своей текущей формой?
2. Я отредактировал вопрос, чтобы включить форму
Ответ №1:
Вам нужно ограничить набор запросов в вашем ModelForm
. А ModelForm
будет, таким образом, выглядеть так:
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)
Комментарии:
1. На мой взгляд, есть ли способ, которым я могу сделать что-то подобное
Watched.objects.filter(Link.objects.filter(user=request.user)
. Я знаю, что мой образец сумасшедший. Но из внешнего запроса я хочу захватитьLink
объекты, созданные пользователем, отправившим запрос2.@Сэмми: да, вы можете фильтровать с
Watched.objects.filter(link__user=request.user)
помощью . Таким образом, это приведет к извлечению всехWatched
объектов, для которых существует связьLink
с asuser
request.user
.3. Я это должно быть добавлено в качестве ответа, чтобы я мог отметить его
4. @Sammy: обновлена фильтрация в форме модели.