I have an application where each user who has previously authenticated can access the index.html page with a button to trigger a time.sleep(t) function.
What I would like is that the same user cannot retrigger the function.
urls.py
from . import views
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('page1', login_required(function=views.page1, login_url="login"), name="page1"),
]
views.py
def page1(request):
if(request.GET.get("arg")=="nap" and request.session.get("nap") == None):
request.session["nap"] = True
sleep(1, 5)
request.session["nap"] = None
return render(request, 'page1.html')
def sleep(t, n):
for i in range(0,n):
time.sleep(t)
print(f"nap n°{i}")
index.html
<button type="button">
NAP
</button>
Related
i ve been stuck for days now trying to find a way to solve this, i am trying to return the specific profile of user that created a post in django but when i try it i get a VectorDetails() missing 1 required positional argument: 'pk'. Let me show my views.py and urls.py
Views.py (views for showing the posts and returning specific users )
def VectorDetails(request, pk, vectors_slug):
vector = get_object_or_404(Vectors, slug=vectors_slug)
vectors = Vectors.objects.filter(status='published').order_by('?')[:6]
creators = Profile.objects.filter(creator=True)
creator = Profile.get_object_or_404(pk=pk)
context = {
'vector': vector,
'vectors': vectors,
'creators':creators
}
return render(request, 'vector-details.html', context)
views.py (view for returning the specific user)
from django.shortcuts import render, get_object_or_404
from userauths.models import Profile
def creator_profile_detail(request, pk):
creators = get_object_or_404(Profile, pk=pk)
context = {
'creators': creators
}
return render(request, 'creator_profile_detail.html', context)
urls.py
from django.urls import path
from . import views
app_name = 'creators'
urlpatterns = [
path('<int:pk>', views.creator_profile_detail, name="creator_profile_detail"),
]
template.html
<div class="premium_uyhau mt-4">
<div class="urip_widget_avater">
<img src="{{vector.creator.profile.image.url}}" class="img-fluid circle" alt="">
<div class="veryfied_author"><img src="assets/img/verified.svg" class="img-fluid" width="15" alt=""></div>
</div>
<div class="widget_avater_124">
<h4 class="avater_name_214">{{vector.creator|title}}</h4>
<span>{{vector.creator.profile.bio|title}}</span>
</div>
</div>
This was how i fixed the bug
def profile(request, username):
if request.user.is_authenticated:
user = get_object_or_404(User, username=username)
profile = Profile.objects.get(user=user)
...
Then in main project urls.py add
path('u/<username>/', profile, name="profile"),
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('', views.Index, name='Index'),
path('register/', views.register, name='register'),
path('login/', views.login, name='login'),
path('register/reg_done/', views.reg_done,),
]
Above is my urls.py. What I am trying is to get my reg_done page come up as after a user click on the submit button to save the regestration info. But its showing that this page not found.
I tried to change the path in form action as register/reg_done/. But then it showed the same error with register/register/reg_done.
In HTML I am giving form action the value"/reg_done", that's it.
Below is my views.py
from django.shortcuts import render
from django.http import HttpResponse
import sqlite3
# Create your views here.
def Index(request):
return render(request, 'index.html')
def register(request):
return render(request, 'register.html')
def login(request):
return render(request, 'login.html')
def reg_done(request):
name = request.POST.get('name')
mail = request.POST.get('mail')
phone = request.POST.get('phone')
psw = request.POST.get('psw')
pswr = request.POST.get('pswr')
all = [name, mail, phone, psw, pswr]
return render(request, 'reg_done.html', {'all':all})
I assume the register view handles the registration. In the form for the register.html file,
Do:
<form action="/register/reg_done" method="post">
your form fields here
</form>
if you want to go with pure HTML solution. If you want something more Django-ly, use the url template tag:
<form action="{% url 'reg_done' %}" method="post">
your form fields here
</form>
I'll advice the later to ensure you avoid "premium developer tears".
In views.py, add this to the top of the file:
from django.views.decorators.http import require_POST
Then edit the reg_done view to:
#require_POST
def reg_done(request):
name = request.POST.get('name')
mail = request.POST.get('mail')
phone = request.POST.get('phone')
psw = request.POST.get('psw')
pswr = request.POST.get('pswr')
all = [name, mail, phone, psw, pswr]
return render(request, 'reg_done.html', {'all':all})
Next, change the path for reg_done in urls.py to:
path('register/reg_done/', views.reg_done, name='reg_done'),
The problem lies in your usage of urls. You should reference the reg_done view as /register/reg_done instead of register/reg_done. The former treats it as an url relative to the domain name while the latter treats it as relative to the current page. That's why coming from the register view and going to the latter yields register/register/reg_done rather than what you want: register/reg_done.
I reused similar code twice but on one occasion it doesn't add anything to database, can anyone tell me why? Lack of form validation is the problem?
I'm trying to increase some user model fields by certain integer every time form is sent to server. One of them working, one doesn't.
Code below increase amount_comments by one every time:
def add_comment(request, pk):
ticket = get_object_or_404(Ticket, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.ticket = ticket
comment.author = request.user
comment.save()
user = CustomUser.objects.get(username=request.user)
user.amount_comments += 1
user.save()
messages.success(request, ('Comment added!'))
return redirect('show_single', pk=pk)
else:
form = CommentForm()
return render(request, 'add_comment.html', {'form': form})
...and this one doesn't increase contributions for some reason:
def show(request, pk):
if request.method == "POST":
user = CustomUser.objects.get(username=request.user)
user.contributions += 5
user.save()
return redirect('checkout', pk=pk)
ticket = Ticket.objects.get(pk=pk)
comment_list = Comment.objects.select_related().filter(
ticket_id=pk).order_by('-date')
paginator = Paginator(comment_list, 4)
page = request.GET.get('page')
comments = paginator.get_page(page)
key = settings.STRIPE_PUBLISHABLE_KEY
return render(request, 'single_ticket.html', {'ticket': ticket, 'comments':
comments, 'key': key})
I don't get any errors just checking admin panel and user doesn't get his contributions field changed by 5 when amount_comments goes up every time.
CustomUser extends AbstractUser with two fields added:
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
contributions = models.IntegerField(default='0')
amount_comments = models.IntegerField(default='0')
On second occasion checkout.js is the library used for the form:
<form action="{% url 'checkout' ticket.id %}" method="post">
{% csrf_token %}
<script src="https://checkout.stripe.com/checkout.js"
class="stripe-button"
data-key={{ key }}
data-description="Payment"
data-amount="500"
data-currency="gbp"
data-locale="auto">
</script>
</form>
urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('blog/', include('blog.urls')),
path('ticket/', include('ticket.urls')),
path('checkout/', include('checkout.urls')),
path('login/', views.login_user, name='login'),
path('sign_up', views.sign_up, name='sign_up'),
path('logout/', views.logout_user, name='logout'),
path('all_tickets/', views.all_tickets, name='all_tickets')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
checkout app urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('<int:pk>', views.checkout, name='checkout'),
]
tickets app urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('delete/<ticket_id>', views.delete, name='delete'),
path('show/<int:pk>', views.show, name='show_single'),
path('show/<int:pk>/comment/', views.add_comment, name='add_comment'),
path('add', views.add_ticket, name='add_ticket'),
]
You're posting to {% url 'checkout' ticket.id %} which is linked here path('<int:pk>', views.checkout, name='checkout') to views.checkout, not show. So this code (show) was never executed for given form. Change URL pattern name in this template tag to the correct one:
{% url 'show_single' ticket.id %}
I'm new to Django and am having a bit of trouble with forms. I'm trying to display a single text input so that users can enter their phone number and it will be sent to my email. I'm actually going to have it stored in a postgre database but want to get the basics down first. The submit button is being displayed but the text input field isn't. I tried putting the forms.py inside of the views.py to see if the PhoneForm() function and file wasn't importing but that didn't do anything.
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.core.mail import send_mail
from .forms import PhoneForm
# Create your views here.
def index(request):
# Render the index.html template with a context dictionary
return render(request, "index.html")
def get_number(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
#create a form instance
form = PhoneForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
cd['phone_form'],
['siteadmin#example.com'],
)
return HttpResponseRedirect('/thanks/')
else:
form = PhoneForm()
return render(request, 'index.html', {'form': form})
index.html
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
forms.py
from django import forms
class PhoneForm(forms.Form):
phone_form = forms.CharField(widget=forms.TextInput())
EDIT: Adding urls.py (the one in the app)
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^$', views.get_number, name='get_number'),
]
Both urls in urls.py have the same expression r'^$' and django looks for them in order, therefore the first one (index) will always be selected. This links to the index view not the get_number view. This means the form is not passed to the template and the form does not show up.
To solve this move url(r'^$', get_number), to the top of 'urlpatterns'.
Change from {{form}} to {{form.phone_form}} in index.html
I am facing a problem while building a Django web app.
I want that if a user logs into his account, his session should be stored and when he agains visits the login page ,he should be redirected to his home page. I have tried using
Here is my code.
Views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
def index(request):
return HttpResponse("Index Page")
#login_required
def home(request):
ctx = {}
return render_to_response('auth/home.html',ctx, context_instance = RequestContext(request))
Urls.py
from django.conf.urls.defaults import *
from django.contrib.auth.views import login, logout
urlpatterns = patterns('',
url(r'^$','apps.auth.views.index'),
)
urlpatterns = patterns('',
url(r'cc/', login, kwargs = {'template_name' : 'auth/cc.html'} , name = 'cc_login'),
url(r'logout/', logout, name = 'cc_logout'),
url(r'home/','apps.auth.views.home', name = 'cc_home'),
)
I ran into the same situation with my django project.
I solved it by making a view that was similar too:
def login_page(request):
if request.user.is_authenticated():
return redirect(<insert your desired page here>)
else:
return render(<whatever the login page is>)
This way, if the user is logged in, they will be redirected to whatever page you want them to be.
EDIT:
In response to the comments below, I am modifying my answer (original is still above).
Here is what I have done to solve your problem.
from django.contrib.auth.views import login
def custom_login(request, **kwargs):
"""
Redirects the user to the desired page if they are authenticated
"""
if request.user.is_authenticated():
return redirect(<whatever page or view you want them to go to>)
else:
return login(request, **kwargs)
For example, your kwargs could be {'template_name': 'your_login_template.html', 'authentication_form': YourCustomRegistrationFormClass}
If you're using the standard login and registration procedures, just leave the kwargs part blank.
I'm fairly new to Django, but have you tried overriding the default login view?
views.py
from django.contrib.auth import views as auth_views
from django.shortcuts import redirect
def login(request, *args, **kwargs):
if request.method == 'POST':
request.session.set_expiry(0) # Remember user session
if request.user.is_authenticated():
return redirect(USER_PAGE_ADDRESS)
return auth_views.login(request, *args, **kwargs)
urls.py
urlpatterns = patterns('',
url(r'cc/', APP_NAME.views.login, kwargs = {'template_name' : 'auth/cc.html'} , name = 'cc_login'),
...
)