how to handle multiple requests in django at same time - django

if multiple users logs in and query for something at the same time, then how can i recognize which user queried for which thing.
i tried to make a group chat system. the idea is just to make a wall on which all users will post but the problem is how can i know which user requested to post if there r multiple users at same time.
my views.py-
def login(request):
if request.method == 'POST':
post = request.POST
u = user.objects.get(username = post['username'])
if post['password'] == u.password:
request.session['username'] = u.username
return redirect('wall')
else:
return render(request, 'wall/login_page.html')
def wall(request):
if request.method == 'POST':
post = request.POST
if 'logout' in post:
del request.session['username']
return redirect('home')
elif 'post' in post:
posted_by = request.session.get('username', '')
post_content = post['post_text']
post_id = posted_by+''+datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
p = user_post(posted_by = posted_by, post_content = post_content, post_id = post_id)
p.save()
return redirect('wall')
else:
if 'username' in request.session:
posts = user_post.objects.all()
return render(request, 'wall/wall_page.html', {'posts': posts})
else:
return redirect('error')
thanks in advance

request has a user attribute that indicates which user made the request (which may be the AnonymousUser if you don't require logins).

Related

Django testing view with pytest

Could you please helpe me debugging this test? I got this error (I don't know whay since, I
have no pk in view): django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.I think the error is due to pk=request.user.id passed as argument in User objects in the view function.
class TestViews(TestCase):
def setUp(self):
self.client = Client()
self.create_campaign_naming_tool_url = reverse('create_campaign_naming_tool')
self.user = User.objects.create_user(
username = 'admin',
email = 'admin#sigma.fr',
password = '1234'
)
def test_create_campaign_naming_tool(self):
response = self.client.get(self.create_campaign_naming_tool_url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'form.html')
Here is my view
def create_campaign_naming_tool(request):
current_user = User.objects.get(pk=request.user.id)
form = CampaignNamingToolForm(initial={'user': current_user})
context = {
'form': form,
}
if request.method == 'POST':
campaign = CampaignNamingTool(user=current_user)
form = CampaignNamingToolForm(request.POST, instance=campaign)
if form.is_valid():
form.save()
messages.success(request, "Your campaign haven ben\
success fully created.")
return render(request, 'form.html', context)
return render(request, 'form.html', context)
You did not login the user in the test:
class TestViews(TestCase):
def setUp(self):
self.client = Client()
self.create_campaign_naming_tool_url = reverse('create_campaign_naming_tool')
self.user = User.objects.create_user(
username = 'admin',
email = 'admin#sigma.fr',
password = '1234'
)
self.client.login(username='admin', password='1234')
# …
It also makes no sense to do such query to fetch the user: request.user is a User object, so you can work directly with this:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
#login_required
def create_campaign_naming_tool(request):
form = CampaignNamingToolForm(initial={'user': request.user})
if request.method == 'POST':
campaign = CampaignNamingTool(user=request.user)
form = CampaignNamingToolForm(request.POST, instance=campaign)
if form.is_valid():
form.save()
messages.success(request, 'Your campaign has been successfully created.')
return redirect('name-of-some-view')
context = {
'form': form,
}
return render(request, 'form.html', context)
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.

Displaying Django Models data in html file

I want to display data taken from my Django models in my html file. So in the code bellow instead of a 0 I want the donation model data. Can someone please help? Thank you! also if anyone knows a easier way please tell me. i can update my question again if anyone needs more details.
Views.py
from django.forms import ModelForm
# Create your views here.
def index(request,*args, **kwargs):
return render(request, "index.html", {} )
#login_required(login_url='/login/')
def myview(request,id):
data= userdetails.objects.get(id=id)
return render(request,'dashboard.html',{'data':data}
def register(request ):
if request.user.is_authenticated:
return redirect('/dashboard/')
else:
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been successfully created, {username} ')
return redirect('loginpage')
context = {'form': form}
return render(request, "register.html", context )
def loginpage(request):
if request.user.is_authenticated:
return redirect('/dashboard/')
else:
if request.method == 'POST':
username = request.POST.get('username')
password =request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/dashboard')
else:
messages.error(request, 'Username OR password is incorrect')
context = {}
return render(request, 'login.html', context)
def logoutuser(request):
logout(request)
return HttpResponseRedirect('/login/')
#login_required(login_url='/login/')
def donate(request):
if request.method == "POST":
title = request.POST['donationtitle']
phonenumber = request.POST['phonenumber']
category = request.POST['category']
quantity = request.POST['quantity']
location = request.POST['location']
description = request.POST['description']
ins = Donation(title = title, phonenumber = phonenumber, category = category, quantity = quantity, location = location, description = description, user=request.user, )
ins.save()
return render(request,'donate.html')
Error:
File "C:\Users\jbtai\coding\GoodDeedWeb\home\views.py", line 30
def register(request ):
^
You need a view that handle that:
def myview(request):
id = request.user.id
data= userderails.objects.get(id=id)
return render(request,'dashboard.html',{'data':data}
Then in your template 'dashboard.html' you could show details:
{{data.donations}}
{{data.points}}
use this url for that view instead of the old one
path('dashboard/',views.myview, name = 'dashboard' ),

passing object between forms and views

I have a problem with passing object between views and forms and back.
On first form i check token (GET) with email - if it's ok - you can go further. If not - go away :D
views.py:
def login(request):
try:
token = request.GET['token']
except:
return render(request,'error.html')
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/vote/')
else:
form = LoginForm(initial={'token': request.GET['token']})
return render(request,'login.html', context = {'form':form})
forms.py:
class LoginForm(forms.Form):
email = forms.EmailField(label='Email', max_length=254,widget=forms.TextInput(attrs={'class':'required'}))
token = forms.CharField(widget=forms.HiddenInput())
def clean(self):
cleaned_data = super().clean()
try:
voter = Person.objects.get(email__iexact=cleaned_data['email'],token__exact=cleaned_data['token'])
except Person.DoesNotExist:
raise ValidationError('Invalid email')
It works.
But now i try to go to voting form.
And I want to use voter object (which is set in LoginForm). Of course this is different form, so I have to pass it. I thought about session, but there's no request.session in form. This is in view, but there's no voter... or is it?
As always when I'm stuck for many minutes, I wrote the question and after few minutes I got excellent solution, so I want to share it with you:
I moved checking into view and use form.add_error. And I don't need token hidden field anymore:
forms.py:
class LoginForm(forms.Form):
email = forms.EmailField(label='Email', max_length=254,widget=forms.TextInput(attrs={'class':'required'}))
views.py:
def login(request):
try:
token = request.GET['token']
except:
return render(request,'error.html')
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
try:
voter = Person.objects.get(email__iexact=form.cleaned_data['email'],token__exact=token)
return HttpResponseRedirect('/vote/')
except Person.DoesNotExist:
form.add_error('email','Invalid email')
else:
form = LoginForm()
return render(request,'login.html', context = {'form':form})
And now I can pass voter into next form using request, session, whatever :D

form not visible on browser even with my get and post methods implemented in django 10.5

class Profile(View):
"""User Profile page reachable from /user/<username> URL"""
def get(self, request, username):
params = dict()
user = User.objects.get(username=username)
tweets = Tweet.objects.filter(user=user)
params["tweets"] = tweets
params["user"] = user
return render(request, 'profile.html', params)
class PostTweet(View):
"""Tweet Post form available on page /user/<username> URL"""
def post(self, request, username):
form = TweetForm(self.request.POST)
if request.method == 'POST':
if form.is_valid():
user = User.objects.get(username=username)
tweet = TweetForm(text=form.cleaned_data['text'],
user=user,
country=form.cleaned_data['country'])
tweet.save()
words = form.cleaned_data['text'].split(" ")
for word in words:
if word[0] == "#":
hashtag,created=HashTag.objects.get_or_create(name=word[1])
hashtag.tweet.add(tweet)
return HttpResponseRedirect('/user/'+user)
else:
form = TweetForm()
return render(request, 'profile.html',{'form':form})
You must make both methods in a single view class.
So on get user gets empty form, and on post form gets processed.

Django Database is updating every on page load

def group_display(request, group_id):
groups = Groups.objects.get(id=group_id)
username = UserInfo.objects.get(owner = request.user)
form = membership_form()
template = 'groups.html'
if request.method == 'POST':
form = membership_form(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.name = username
post.group = groups
post.save()
context = {
'form':form,
}
return render(request, template, context)
The problem is that every time I reload page a new row is added to membership model. Seems like the page is loads as request.POST. is there any way i can insert the data only on button click?
After a successful POST request, it is best to return a redirect. This prevents the post request from being processed again if the page is refreshed. You can redirect to the current url if you want.
from django.shortcuts import redirect
def group_display(request, group_id):
...
if request.method == 'POST':
form = membership_form(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.name = username
post.group = groups
post.save()
return redirect('/success-url/')
...
There are two things you can do:
Redirect after a successful POST.
Check to make sure there isn't a registration for that user.
Here is a view that takes care of both:
from django.shortcuts import get_object_or_404, redirect
def group_display(request, group_id):
groups = get_object_or_404(Groups, id=group_id)
username = get_object_or_404(UserInfo, owner=request.user)
if username.membership_set.exists():
# This user is already enrolled
return redirect('/')
form = membership_form(request.POST or {})
template = 'groups.html'
context = {'form': form}
if form.is_valid():
post = form.save(commit=False)
post.name = username
post.group = groups
post.save()
return redirect('/')
return render(request, template, context)
You'll have to adjust username.membership_set.exists based on your own models.