Issues redirecting in Django - python

I'm deploying a django app, and I have two forms: One for rating and another for contact in the home page. Both of them redirect to the home page after save a model. The contact form works fine, but the rating form keeps the post url and doesn't save the model, and after doing it again, it save it.
For example, I'm in www.site.com, then I send a post request from the rating form, the form redirect me to www.site.com/rating/ without saving the data. Then, if I'm send from www.site.com/rating/ the same form, the data is saved and redirect to www.site.com/rating/rating/ (404). The contact form works fine with the same process, and I think both are similar. The contact form redirects me to www.site.com like I want. I don't know why is this happening.
urls.py
urlpatterns = i18n_patterns(
url(r'^admin/', admin.site.urls),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^', include('myapp.urls')),
prefix_default_language=False
)
myapp/urls.py
urlpatterns = [
url(r'^contact/', views.contact, name='contact'),
url(r'^rating/', views.raiting, name='rating'),
url(r'^', views.index, name='home'),
]
myapp/views.py
def contact(request):
if request.method != 'POST':
raise Http404('acceding from GET')
msg = ContactForm(request.POST)
if not msg.is_valid():
context = {
'contact_errors': msg.errors
}
return render(request, 'home.html', context)
msg.save()
return redirect('home')
def rating(request):
if request.method != 'POST':
raise Http404('acceding from GET')
msg_form = OpinionForm(request.POST)
if not msg_form.is_valid():
context = {
'rating_errors': msg_form.errors
}
return render(request, 'home.html', context)
msg = msg_form.save(commit=False)
if 'picture' in request.FILES:
msg.picture = request.FILES['picture']
msg.save()
return redirect('home')
the forms in home.html
<form action="{% url 'rating' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input name="name" type="text" class="form-control" placeholder="Your name" required>
<textarea name="text" id="" cols="30" rows="5" class="form-control" placeholder="Your comment" required></textarea>
<input name="picture" type="file" id="upload-photo">
<input type="submit" class="button" value="Send">
</form>
<form action="{% url 'contact' %}" method="post">
{% csrf_token %}
<input name="email" type="text" class="form-control" placeholder="Email" required>
<textarea name="message" id="" cols="30" rows="5" class="form-control" required placeholder="Your message"></textarea>
<input type="submit" class="button" value="Send">
</form>

I guess that this is a typo, but check your urls.py:
url(r'^rating/', views.raiting, name='rating'),
should be rating instead o raiting, right?

Related

How to use a Django (Python) Login Form?

I builded a login form in Django. Now I have a problem with the routing.
When I select the login button, the form doesn`t send the correct awnser.
I think the form in the frontend cannot gets the correct awnser from the
view.py file. So it will send no awnser and the login process canot work and
the form is a simple static html form.
I hope you can help me.
HTML:
<form class="windowlogscreen-content" method="POST">
{% csrf_token %}
<input type="text" placeholder="account" name="username">
<br>
<input type="password" placeholder="password" name="password">
<br>
<button style="margin: 20px;" type="submit">join</button>
</div>
</div>
</form>
views.py
def loginuser(request):
if request.method == "POST":
username = request.POST['accountName']
password = request.POST['accountPassword']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return views.homepage
else:
return redirect('start')
else:
return render(request, 'start', {})
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', start),
path('homepage/', include('homepage.urls'))
]
homepage urls.py
urlpatterns = [
path('login/', views.login, name="login"),
path('register/', views.register, name="register"),
path('', views.homepage, name="homepage"),
path('account/', views.account, name="account")
]
def login(request):
if request.method = 'POST':
username = request.POST['username']
password = request.method = POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect(#User to the dashboard!)
else:
message.info(request, "invalid credentials")
return redirect('login')
else:
return render(request, 'login.html')
Login.html:
<form method="POST" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group">
<label class="text-primary text-dark font-weight-bold">Enter Username</label>
<input type="text" class="form-control" name="username" placeholder="Enter Username">
</div>
<br>
<div class="form-group">
<label class="text-primary text-dark font-weight-bold">Enter Password</label>
<input type="password" class="form-control" name="password" placeholder="Enter Password">
</div>
<br>
<button type="submit" class="btn btn-primary btn-lg">Log in</button>
</form>
Docs

Two HTML Forms in one DJango views

I have two simple HTML forms on one page. I want to create Django view to submit multiple Django forms. I can submit form1 but I have no clue how to submit form2.
There is lot of material on internet but they are all about Djanog forms. Please help me with HTML form submission.
HTML Form
<form action="" method=post name="form1" id="form1">
<input type="text" id="input_form1" name="input_form1">
<button type="submit">Submit</button>
</form>
<form action="" method=post name="form2" id="form2">
<input type="text" id="form2" name="form2">
<button type="submit">Submit</button>
</form>
Views.py
def index(request):
if request.method == 'POST':
input_form1 = request.POST.get('input_form1')
return render(request, 'index.html', params)
Please elaborate how to integrate form2 in Views.py
you can put hidden input inside of each form to identify them
index.html
<form action="" method="post">
{% csrf_token %}
<input type="text" id="input_form1" name="input_form1">
<button type="submit">Submit</button>
<input type="hidden" name="which_form_is_it" value="this_is_form_1">
</form>
<form action="" method="post">
{% csrf_token %}
<input type="text" id="input_form2" name="form2">
<button type="submit">Submit</button>
<input type="hidden" name="which_form_is_it" value="this_is_form_2">
</form>
views.py
def index(request):
if request.method == 'POST':
#watch output in console
print(request.POST)
which_form_is_submiting = request.POST["which_form_is_it"]
if str(which_form_is_submiting) == "this_is_form_1":
#here is yor logic for data from form 1
form_1_input = request.POST["input_form1"]
if str(which_form_is_submiting) == "this_is_form_2":
#here is your logic for data from form 2
form_2_input = request.POST["input_form2"]
return render(request, 'index.html', params)

how to call function of views.py using modal <form action=" ">?

I have a login modal in base.html. on clicking the login button modal gets open. I want that when the form has submitted the action='login' should call the login function of views.py but when I try to submit, it redirects the page to the login page which does not exist ('http://127.0.0.1:8000/login'). I want to know how can I call login function of views from modal, if I'm not wrong then action='' attribute calls the function and not the page. I tried removing the path of login from urls.py.
base.html
<div class="modal fade" id="modalLoginForm">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- Default form login -->
<form class="text-center border border-light" action="login" method="post" autocomplete="off">
{% csrf_token %}
<!-- Email -->
<input type="text" name="username" class="form-control mb-4" placeholder="E-mail" required>
<!-- Password -->
<input type="password" name="password" class="form-control mb-4" placeholder="Password" required>
<div class="d-flex justify-content-around">
<div>
<!-- Remember me -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="defaultLoginFormRemember" name="remember_me">
<label class="custom-control-label" for="defaultLoginFormRemember">Remember me</label>
</div>
</div>
<div>
<!-- Forgot password -->
Forgot password?
</div>
</div>
<!-- Sign in button -->
<input class="btn btn-info btn-block my-3" type="submit" value="Sign in">
</form>
<!-- Default form login -->
</div>
</div>
</div>
views.py
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('/')
else:
messages.info(request, 'invalid credentials')
return redirect('index')
else:
return render(request, 'index.html')
app urls.py
urlpatterns = [
path('', views.login, name='login'),
path('register',views.register, name='register'),
path('logout', views.logout, name='logout')
]
project urls.py
urlpatterns = [
path('', include('camroid_app.urls')),
path('accounts/', include('accounts_app.urls')),
path('admin/', admin.site.urls),
]
how can i call login() of views from <form action='login'>
as it is raising error: The current path, login, didn't match any of these.
how can i call function of views directly from <form action='login'>
try:
action="{% url 'login' %}"
or
action="/"

How do I save form response as an object in Django's database?

I am unable to save my form responses to the database as an object in Django.
Everytime I click on submit to submit my form, I am just logged out of my website and the object isnt saved in the database either.
Can anyone tell me where I am going wrong?
This is my models in models.py.
class Chain(models.Model):
name = models.CharField(max_length=255)
user = models.ForeignKey(User, on_delete=models.CASCADE)
year = models.CharField(max_length=10, default="20XX")
sem = models.CharField(max_length=30, default="Default Semester")
code = models.CharField(max_length=10, default="SUB-CODE")
slot = models.CharField(max_length=10, default="EX+EX")
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
This is my view in views.py file.
#login_required(login_url='/')
def create_course(request):
if request.method == 'GET':
return render(request, 'create_course.html', {})
elif request.method == 'POST':
name=request.POST['name']
year=request.POST['year']
sem=request.POST['sem']
code=request.POST['code']
slot=request.POST['slot']
newchain = Chain(
name=name,
year=year,
sem=sem,
code=code,
slot=slot,
)
newchain.user = request.user
newchain.save()
return redirect('success')
This is my HTML code for the form.
{% extends 'authmain.html' %}
{% block content %}
<h3> <p class="text-center"> Create a new Course Blockchain: </p> </h3>
<div class="card border-dark mb-3 mx-auto" align="center" style="width: 40rem;">
<div class="card-body">
<h5 class="card-title">
<form method='POST'>
{% csrf_token %}
<label for="year">Year: </label>
<input type="text" id="year" name="year" value=""><br>
<label for="code">Course Code: </label>
<input type="text" id="code" name="code" value=""><br>
<label for="name">Course Name: </label>
<input type="text" id="name" name="name" value=""><br>
<label for="slot">Slot: </label>
<input type="text" id="slot" name="slot" value=""><br>
<label for="sem">Semester: </label>
<input type="text" id="sem" name="sem" value=""><br>
<button class="btn btn-outline-primary" type="Submit"> Create </button>
</form>
</h5>
</div>
</div>
{% endblock %}
This is my urls.py.
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.home, name="home"),
path('register/', views.register, name="register"),
path('logout/', views.logoutuser, name="logoutuser"),
path('dashboard/', views.dashboard, name="dashboard"),
path('create_course/', views.create_course, name="create_course"),
path('success', views.success, name="success"),
]
This is the view function for success.
#login_required(login_url='/')
def success(request):
return render(request, 'success.html', {})
The issue is that you are not closing form tag in the authmain.html.
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<form action="{% url 'logoutuser' %}" method='POST'>
{% csrf_token %}
<button class="btn btn-outline-info mb-auto" type="submit">Logout</button>
----- CLOSING FORM TAG MISSING HERE ---
</li>
</ul>
and when you submit the form at Create Course, you actually trigger this form, which logs out the user. Add closing tag to the logout form and you'll fix your problem.
Sometimes debugging can be a bit tricky.
To save directly in the database in Django use Model.objects.create()
Chain.objects.create(user=request.user, name=name, year=year, sem=sem,
code=code, slot = slot)
You need to use a model form to achieve this
class MyForm(ModelForm):
class Meta:
model = MyModel
fields = []
And then you can do something like this:
form = MyForm(request.POST)
if form.is_valid():
new_item = form.save()
...
And it will save directly to the database.

django link to another page does render new page

What I am trying to do:
I want to click a link on my page and then be redirected to another of my pages.
login.html:
{% block body %}
<h1>Login</h1>
{% if message %}
<div>
{{ message }}
</div>
{% endif %}
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
<input name="username" type="text" />
<input name="password" type="password" />
<input type="submit" value="Login" />
</form>
<a class="btn btn-primary" href="{% url 'new_user' %}">New user</a>
{% endblock %}
new_user.html:
{% block body %}
<h1>New user</h1>
{% if message %}
<div>
{{ message }}
</div>
{% endif %}
<form action="{% url 'new_user' %}" method="post">
{% csrf_token %}
<input name="username" type="text" />
<input name="password" type="password" />
<input name="email" type="email" />
<input type="submit" value="Login" />
</form>
{% endblock %}
urls.py in main app:
urlpatterns = [
path("", include("orders.urls")),
path("new_user/", include("users.urls")),
path("login/", include("users.urls")),
path("admin/", admin.site.urls),
]
urls.py in users:
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("new_user", views.new_user_view, name="new_user")
]
views.py:
def index(request):
if not request.user.is_authenticated:
return render(request, "users/login.html", {"message": None})
context = {
"user": request.user
}
return render(request, "users/user.html", context)
def login_view(request):
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "users/login.html", {"message": "Invalid credentials."})
def new_user_view(request):
username = request.POST["username"]
password = request.POST["password"]
user = User.objects.create_user(username=username, password=password)
if user is not None:
user.save()
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "users/new_user.html", {"message": "Invalid credentials."})
Behavior:
What happens is I go to localhost:8000/login press the link for a new user, my browser redirects me to localhost:8000/new_user but is still rendering login.html and not new_user.html
What am I missing?
Change this
urlpatterns = [
path("", include("orders.urls")),
path("new_user/", include("users.urls")),
path("login/", include("users.urls")),
path("admin/", admin.site.urls),
]
to this
urlpatterns = [
path("", include("orders.urls")),
path("", include("users.urls")),
path("admin/", admin.site.urls),
]
All URLs from users will be included.
path("new_user/", include("users.urls")) would result in additional prefix new_user for all the urls from users. In this case localhost:8000/new_user matches index page from users app. You can try accessing localhost:8000/new_user/new_user with current configuration - it will render the page you're expecting.

Categories

Resources