Django website : make the url adress unchangeable - python

I would like to get your advices in order to block the url modification by my clients.
For example, I have a client in my website and he will redirect to his own page after the log process.
His homepage url looks like : http://localhost:8000/Compagny/id/ with id corresponding to the Compagny1.
For example : http://localhost:8000/Compagny/1/ with 1 is the first Compagny
But, in the url bar, if my client writes : http://localhost:8000/Compagny/2/ he will be redirected to Compagny2's homepage and I don't want this possibility.
My question is :
How I can implement some rules, functions, or anything else in order to set unchangeable the url adress ? Client couldn't change the url and see the homepage which make reference to another client ?
Thank you
EDIT :
This is my homepage view :
#login_required
def HomePage_Compagny(request, id) :
compagny = get_object_or_404(Compagny, pk=id)
intervention = CompagnyIntervention.objects.filter(Compagny__id=id).all()
pointsajoutes = CompagnyAjout.objects.filter(Compagny__id=id).all()
coefficient = CoefficientIntervention.objects.last()
if request.method == 'POST':
form_ajout = ContratAjoutFormulaire(request.POST or None)
if form_ajout.is_valid() :
#Several processes
return HttpResponseRedirect('http://mywebsite/'+id)
else:
form_ajout = ContratAjoutFormulaire()
context = {
...
}
return render(request, 'CompagnyHomePage.html', context)
My url for this part is : url(r'^Compagny/(?P<id>\d+)/$', views.Homepage_Compagny, name="Homepage"),

You can't prevent the user from typing a url in their browser. Instead, you should restrict access in the view, and return 404 if the user is not allowed to access that company.
For example, if the Compagny has a foreign key to User, then you could do:
#login_required
def HomePage_Compagny(request, id) :
compagny = get_object_or_404(Compagny, pk=id, user=request.user)
...

In your views.py file where you wrote the function for the page you should use user=request.user with this given you can apply multiple methods to block users from specific sites.
use the if user.is_authenticated(): method in views.
give users a group and deny access to specific pages
check in the template if the current user is allowed to see the site
If a user visits a url you can redirect him to the main page or display a 404 or tell him that he does not have access rights for this site.
For Example in the template you can display an error message like:
{% if request.user == pageowner %}
the site code
{%else%}
<h1>This is not your Site. Please Go back</h1>
{%endif%}
in the views.py function you would have to define a "pageowner" attribute where you define a user who "owns" or at least created that Page.

Related

Page not found http://127.0.0.1:8000/manageAccount/a/delete

I don't know why I get this page because I think all works right. I couldn't identify why the browser gives this error but below url is not worked because user object not get because its redirect on login page but i am going on this url http://127.0.0.1:8000/user_homeview/a/delete its work successfully but user_homeview that template is after login show means homepage i dont know what can i do please tell me:
Page not found http://127.0.0.1:8000/manageAccount/a/delete
Here is my code:
template.html:
Delete Account<Br>
urls.py:
path('<str:username>/delete', delete_user, name='delete-user')
views.py:
def delete_user(request, username):
context = {}
u = User.objects.filter(username=username)
u.delete()
messages.success(request,'your account delete')
return render(request, 'home/login.html', context=context)
Check on your developer tools what is being rendered on your href attribute. I think the url is not being rendered correctly by your current template tag. It should be like this, according to Django's documentation:
Delete Account<Br>
Note that you don't have access to request by default in your templates. If you are deleting a user by its username, the previous code would be:
Delete Account<Br>
as user is accessible by default in your templates.
Be aware that this is not the secure way of deleting users, as anyone with other user's information can access this link to delete accounts. You should use POST requests and check if the user requesting the delete link is the owner of the account.

Working with forms in Django and checking if all the input fields are entered

I have created a contact page and there I created a form that looks like this
Now I want that 'submit' button to check whether all the input fields are entered. If it is then I want to activate the
<form action="{% url 'contact' %}" method="post">
Otherwise no post method activation. Instead a popup message box will appear telling that "Please enter all the fields"
If post method is activated, I want to go to the {% url 'contact' %} that is my views.py file and check if the system is able to retrieve all the values from the input fields.
If it does it will render a fresh contact page return render(request, 'myapp/contact.html')
And popup another message box to the browser that "Form is submitted successfully"
Else another message box to the browser that "There is an error occurred submitting the form"
I really can't find a way to implement this. I am a newbie is Django and Python. I have very minimum experience in html and CSS. But no JavaScript, though I used a small JavaScript code, I wish to completely use Python, HTML and CSS. Is that possible to implement this scenario using my desired language?
If yes, please tell me how.
You can do it on client side validation. To validate, none of the fields should be left blank. Like this
function validateForm() {
var isValid = true;
$('.form-field').each(function() {
if ( $(this).val() === '' )
confirm("All Fields are required!");
isValid = false;
});
return isValid;
}
I would recommend using Django forms. https://docs.djangoproject.com/en/3.0/ref/forms/api/#django.forms.Form
Create a contact form with the form class, pass it into the template. It will make the HTML tags for default browser validation. It will also allow backend validation when the form is submitted. You can then redirect the user if the form is valid or invalid.
If you wanted to do it from scratch you could do the following.
In your HTML make sure you add required attribute to the required input fields
<input name="name" type="text" ... required ... >
Import messages from django messages, check user input is valid, add message and render contact.html . This will send a message into the template. You can style the message with HTML and CSS.
In views.py
from django.contrib import messages
if request.method == POST:
...
name = request.POST.get('name')
if name == '':
messages.warning(request, 'Please enter name !')
return render(request, 'myapp/contact.html')
...
look at my code if simple just make an if statement like I did look the second and third line
def signup(request):
if request.method == 'POST':
if request.POST['password1'] == '':
return render(request, 'accounts/signup.html', {'error': 'Please fill all the fileds '})
elif request.POST['password1'] == request.POST['password2']:
(YOUR CODE HERE )

render_to_response or redirect changes the template elements in Django 1.8

I'm trying to check if email id entered by user is existing in the database table, if existing - I would like to route to 'prof.html' template otherwise just show a message in the login.html template.
Both the conditions are working fine.
However, the problem is when I use redirect() or render_to_response() -
the destination template elements like div, input etc., are being changed automatically (prof.html in this case) ?
Can we also send the context information to destination template ?
(response data or any object from the database and redirect to prof.html template via view in this case)
Below is my code :
Views.py
def verifyme(request):
if request.method == "POST":
emailid4loginV = request.POST['emailid4login_Aj']
else:
emailid4loginV = ''
response_data = ''
return HttpResponse(response_data, content_type="text/plain")
response_data = ''
if Employee.objects.filter(email = emailid4loginV).exists():
response_data='Thanks for waiting - login successful'
#return render_to_response('app/prof.html', { 'response_data':response_data},
# context_instance = RequestContext( request ) )
return redirect('/myprofile')
else:
response_data='Ouch! you are not a registered user!'
return HttpResponse(response_data, content_type="text/plain")
urls.py
url(r'^myprofile$', 'app.views.profile', name='profile'),
Just for your info, 'profile' view does return some objects from the table and renders in the template app/prof.html.
I observed that the destination template is being rendered in same login.html template (How ? : In the browser url, I dont see myprofile - but the one for login) But when I request the myprofile manually by entering in the website url (localhost:xxxxx/myprofile), it works perfectly :(
URL before submitting request in login.html :
URL after submitting request in login.html - myprofile is rendered in the same page :
When I manually type in the url, template just works perfectly..
Could you please let me know what could be the problem ?
EDIT:
Solved this issue with a little trick, posted in the below
https://stackoverflow.com/questions/31091938/why-is-httpresponseredirectreverse-doesnt-redirect-to-new-page
1) Actually there are many ways to pass data to next view ... generally in such cases like you have better way - using sessions (cookie|localstorage|sessionstorage), it is like clipboard ... save session data in one view and get it later in another one. For example:
First view:
self.request.session['response_data'] = 'some text'
self.request.session.set_expiry(0) # user’s session cookie will expire when the user’s Web browser is closed.
Other views:
response_data = self.request.session.get('response_data', '')
But if you planning just use this data in template Django has some kind more high-level interface for it and in your case semantically right to use it - The messages framework https://docs.djangoproject.com/en/1.8/ref/contrib/messages/
2) If you want redirect to another view better use url namespaces and reverse https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
return HttpResponseRedirect(reverse(app.views.profile)) # here I've passed callable object because you have not show your app url namespace, but generally use namespaces
https://docs.djangoproject.com/en/1.8/topics/http/urls/#url-namespaces

How to render an html template with data from view?

I am new to django. I made a form. I want that if the form is filled successfully then django should redirect to a success page showing the name entered in the form but no parameters should be present in the url itself.
I searched on the internet and the solution I got was to redirect to url with pk as a get parameter which fetches the data and shows in the view. But I don't want to pass any thing in the url itself. and some websites say that http can't redirect with post data.
Here's my views.py
class UserRegistrationView(CreateView):
model = UserForm
template_name = 'userregistration.html'
form_class = UserForm
success_url = 'success'
def get_success_url(self):
return reverse('success',kwargs = {'name' : self.object.firstName})
and here's the template to which I want to redirect:
<h2>Congratualations for registering {{name}} </h2>
Basically what I want is that if the person fill form mentioning his/her firstName as "xyz" then the redirected success page should say that "Congratulations for registering xyz"
You can use django sessions, which I believe installed by default in 1.8
Look here
# Set a session value:
request.session["fav_color"] = "blue"
# Get a session value -- this could be called in a different view,
# or many requests later (or both):
fav_color = request.session["fav_color"]
# Clear an item from the session:
del request.session["fav_color"]
You can pass your pk via session and extract your object in another view without affecting your url.
Make sure you clean up after yourself.
Let me know if more help needed.
One of the possible ways of passing data between views is via sessions. So, in your UserRegistrationView you need to override the form_valid method as shown below.
class UserRegsitrationView(CreateView):
def form_valid(self,form):
self.request.session['name'] = self.object.firstName
return super(UserRegistrationView,self).form_valid(form)
class SuccessView(TemplateView):
template_name = "success_template.html"
def get_context_data(self,**kwargs):
context = super(SuccessView,self).get_context_data(**kwargs)
context['name'] = self.request.session.get('name')
del self.request.session['name']
return context
One more thing that you can modify in your code is that you need not declare success_url if you are overriding get_success_url

passing GET parameter from python view to template

As simple as this is, I'm having trouble getting the value of a GET parameter d
I'm clicking on a link like:
http://127.0.0.1:8000/Account/Site/d=mysite.com
The view that, that url serves is:
#login_required
def Site(request):
if request.user.is_authenticated():
# verify domain in url is associated with authenticated users account
DomainToScan = request.GET.get('d')
VerifyDomainAgainstDb = Tld.objects.filter(FKtoClient=request.user,domainNm=DomainToScan)
else:
HttpResponseRedirect("/Login/")
return render(request, 'VA/account/begin_site.html', {
'Site':Site,
'VerifyDomainAgainstDb':VerifyDomainAgainstDb
})
specifically, this line:
DomainToScan = request.GET.get('d')
the value of DomainToScan is outputting as None when viewing the django template begin_site.html
What am I doing wrong here?
Thank you!
UPDATE:
urls.py
(r'^Account/Site/[?]d=[A-za-z0-9]{2,50}.[a-z]{1,3}$', Site),
For some reason this isn't matching a url like:
http://127.0.0.1:8000/Account/Site/?d=mysite.com
Any reason why? Rubular says its valid
You don't have any GET parameters. If you want domain to be a GET parameter, your link should be http://127.0.0.1:8000/Account/Site/?d=mysite.com - notice the ?.
(Also note you would need to actually return HttpResponseRedirect(), not just call it: but the whole checking of is_authenticated is pointless anyway because the function is decorated with login_required, so a non-authenticated user wouldn't even get into that view.)
Try:
#login_required
def Site(request, DomainToScan=None):
if request.user.is_authenticated():
# verify domain in url is associated with authenticated users account
VerifyDomainAgainstDb = Tld.objects.filter(FKtoClient=request.user,domainNm=DomainToScan)
else:
return HttpResponseRedirect("/Login/")
return render(request, 'VA/account/begin_site.html', locals())
urls.py
(r'^Account/Site/(?P<DomainToScan>[^/]+)/', Site),

Categories

Resources