I created a forms.ModelChoiceField that contains items on my database, but it show all the users' data. I only want to show data of the connected user! Thanks for helping.
PS: I don't need to create a models.Form because I don't want to edit or update the data.
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})
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
class ListDataForm(forms.Form):
message = forms.CharField(widget=forms.Textarea)
listdata = forms.ModelChoiceField(queryset=List.objects.all())
Instead of forms.ModelChoiceField(queryset=List.objects.all())
I wrote forms.ModelChoiceField(queryset=List.objects.filter(author=request.user))
but it doesn't work.
Use 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)
Pass request
as a argument when you will call Form.
def your_view(request): ...YOUR LOGIC... form = ListDataForm(request) ...YOUR LOGIC...
The issue with your approach is that the queryset
value is executed on class creation, that is, when you first fire up the Python interpreter and load all the Django stuff. The request
object is not created here, but once you start getting requests from users.
As per the documentation , you can do it at class instantiation instead, setting the queryset
parameter to None
and writing
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)
Then, in your view, create this form as follows
def form_view(request):
...
form = ListDataForm(request=request)
...
As per the documentation the correct way to restrict the queryset for ModelChoiceFields is as below.
# 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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.