Django ModelChoiceField получить выбор подключенного пользователя - PullRequest
1 голос
/ 10 марта 2020

Я создал Form.ModelChoiceField, который содержит элементы в моей базе данных, но он показывает все данные пользователей. Я только хочу показать данные подключенного пользователя! Спасибо за помощь.

PS: мне не нужно создавать модели. Форма, потому что я не хочу редактировать или обновлять данные.

views.py

def sms(request):
    form2 = ListDataForm()
    if request.method == 'POST':
        form2 = ListDataForm(request.POST)
        if form2.is_valid():
            message = form2.cleaned_data["message"]
            print(message)

    else:
        form2  = ListDataForm(request=request)
    return render(request, "data_list/sms.html", {"form2": form2})

models.py

class List(models.Model):
    item = models.CharField(max_length=100)
    content = models.TextField()
    site = models.CharField(max_length=11, choices=THE_SITE)
    content_list = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.item

forms.py

class ListDataForm(forms.Form):

    message = forms.CharField(widget=forms.Textarea)
    listdata = forms.ModelChoiceField(queryset=List.objects.all())

Вместо forms.ModelChoiceField(queryset=List.objects.all()) я написал forms.ModelChoiceField(queryset=List.objects.filter(author=request.user)), но это не работает.

Ответы [ 3 ]

2 голосов
/ 10 марта 2020
  1. Использование get_queryset

    class ListDataForm(forms.Form):
    
        message = forms.CharField(widget=forms.Textarea)
        listdata = forms.ModelChoiceField(queryset=get_queryset)
    
        def get_queryset(request):
            return List.objects.filter(author=request.user)
    
  2. Передайте request в качестве аргумента при вызове формы.

    def your_view(request):
        ...YOUR LOGIC...
        form = ListDataForm(request)
        ...YOUR LOGIC...
    
1 голос
/ 26 марта 2020

В соответствии с документацией правильный способ ограничения набора запросов для ModelChoiceFields приведен ниже.

# in your form
class ListDataForm(forms.Form):    
    message = forms.CharField(widget=forms.Textarea)
    listdata = forms.ModelChoiceField(queryset=List.objects.all())

def __init__(self, *args, user=None, **kwargs):
    super().__init__(*args, **kwargs)
    if user:
        listdata = self.fields['listdata']
        listdata.queryset = listdata.queryset.filter(author=user)


# in your view
...
form = ListDataForm(data, ..., user=request.user)
1 голос
/ 25 марта 2020

Проблема с вашим подходом заключается в том, что значение queryset выполняется при создании класса, то есть когда вы впервые запускаете интерпретатор Python и загружаете все вещи Django. Объект request здесь не создается, но как только вы начинаете получать запросы от пользователей.

Согласно документации , вы можете сделать это при создании экземпляра класса, установив queryset параметр в None и запись

forms.py

class ListDataForm(forms.Form):
  ...
  listdata = forms.ModelChoiceField(queryset=None)
  ...

  def __init__(self, *args, **kwargs):
    request = kwargs.pop('request', None)
    super().__init__(*args, **kwargs)
    if request:
      user = request.user
      self.fields['listdata'].queryset = List.objects.filter(author=user)

Затем, по вашему мнению, создайте эту форму следующим образом

views.py

def form_view(request):
  ...
  form = ListDataForm(request=request)
  ...
...