Djnago Template - Url with multiple parameter - python-3.x

I am using Django template. I want to add multiple parameter in URL
currently I am passing only one parameter
my reset_password.html
Click on this link to reset your password
{% if htmlVersion %}
<div>
<a href="{{domain}}{% url 'pweuser:user_password_sms_reset' token %}">
{{domain}}{% url 'pweuser:user_password_sms_reset' token %}
</a>
</div>
{% else %}
{{domain}}{% url 'pweuser:user_password_sms_reset' token %}
{% endif %}
This link will expire in 15 minutes
my urls.py
url(r"^resetPasswordSms/(?P<token>[-\w_=]{28})/$", PasswordResetSmsView.as_view(), name="user_password_sms_reset",),
my views.py
t = loader.get_template("reset_password.html")
c = {"htmlVersion": True, "domain": settings.SITE_DOMAIN, "token": token.token}
htmlVersion = t.render(c)
c = {"htmlVersion": False, "domain": settings.SITE_DOMAIN, "token": token.token}
textVersion = t.render(c)
Here its is working good
in this I want to add more than 1 parameter. means here token is the 1st parameter and I need to add userId as 2nd parameter and need to pass in template..
how can i add multiple parameter in URL and template URL

Here is how you can add multiple parameters in URL:
from django.urls import re_path
urlpatterns = [
re_path(r"^resetPasswordSms/(?P<userId>[0-9])/(?P<token>[-\w_=]{28})/$", PasswordResetSmsView.as_view(), name="user_password_sms_reset")
]
https://docs.djangoproject.com/en/3.1/topics/http/urls/#using-regular-expressions
and template URL:
{% url 'pweuser:user_password_sms_reset' token=value1 userId=value2 %}
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#url
If you have any questions about any part, you can refer to the link below that.

Related

How to check routes on template?

Does anyone know how to check if a template is being accessed through a url route with the django template language?
Here is my situation: There's this template article.html, that shows all posts of a blog when accessed through blog-home url route, and that also shows only posts of a given user through user-posts url route.
This template works like that because what defines which posts will be shown are the classes in views.py.
That being said, here is what I tried to do: (I know its wrong)
{% if url == 'user-posts' %}
"Some HTML h1 tag I want do be shown only when this template is accessed via 'user-posts' url"
{% endif %}
How would be the correct way, if there's any, to write this if statement?
When Django matches a url pattern a ResolverMatch object is created and made available on the request object at request.resolver_match. This ResolverMatch object can be queried in your template to acheive what you want, the url_name attribute is the name of the url pattern that was matched
{% if request.resolver_match.url_name == 'user-posts' %}
You should create a custom templatetag,
my_app/templatetags/utils.py
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def is_active_view(context, *view_names):
request = context.get('request')
for view_name in view_names:
if getattr(request.resolver_match, 'view_name', False) and request.resolver_match.view_name == view_name:
return True
return ''
And use it in your template this way, assuming blog-home is the url name you gave to your url :
blog-home.html
{% load utils %}
{% is_active_view 'blog-home' as display_blog_home_section %}
{% if display_blog_home_section %}
<!-- Your code -->
{% endif %}
NB : this template tag can check after multiple view names at once and support namespaced url :
{% is_active_view 'front:blog-home' 'front:blog-categories' as display %}
Here is a more optimized version of this if you are using boostrap and trying to make the menu options "active" when you are on that URL
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def is_active_tab(context, *view_names):
request = context.get('request')
for view_name in view_names:
if getattr(request.resolver_match, 'view_name', '') == view_name:
return 'active'
return ''
And you use it like
<li class="nav-item {% is_active_tab 'games:list' %}">
<a class="nav-link" href="{% url 'games:list' %}">
{% translate "My Quizzes" %}
</a>
</li>
<li class="nav-item {% is_active_tab 'games:create' %}">
<a class="nav-link" href="{% url 'games:create' %}">
{% translate "New Game" %}
</a>
</li>
It adds an extra active classname to the class of the element if any of the view_names match the current view name. Makes the template writing much cleaner

Djoser override activation email with template

I've been scouring for more information about how to do this, but there seems to be little to no documentation help.
Essentially want I want to do is make a new template for the activation email so the link can start with localhost:3000 instead of localhost:8000 (I'm using Vue for the frontend post request that's why)
I managed to find this: https://github.com/sunscrapers/djoser/blob/master/djoser/templates/email/activation.html
but when I added it to my own project, the default Djoser template is still being used.
This is how my settings.py looks like:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
My activation URL which works if the 8000 is replaced by 3000 manually:
'ACTIVATION_URL': 'registration/activate/{uid}/{token}',
templates/email/activation.html:
{% block subject %}
{% blocktrans %}Account activation on {{ site_name }}{% endblocktrans %}
{% endblock subject %}
{% block text_body %}
{% blocktrans %}You're receiving this email becaus!!!!!!e you need to finish activation process on {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page to activate account:" %}
{{ http }}://{{ localhost:3000 }}/{{ {% url 'registration/activate' uidb64=uid token=token %} }}
{% trans "Thanks for using our site!" %}
I suppose you need to override email.ActivationEmail, for example to core/email.py
from djoser import email
class ActivationEmail(email.ActivationEmail):
template_name = 'email/activation.html'
and add it to your settings.py
DJOSER = {
'EMAIL': {
'activation': 'core.email.ActivationEmail'
}
}
Here are emails which can be overwritten link
You can configure the DOMAIN and SITE_NAME in the settings.py file instead of changing the template.
Just put DOMAIN = ('localhost:3000') and SITE_NAME = ('YOUR_SITE_NAME')
DOMAIN = ('localhost:3000')
SITE_NAME = ('YOUR_SITE_NAME')
DJOSER = {
...
}
Source: https://stackoverflow.com/a/62586798/6568539 (I found that we don't need to use "config" as mentioned in this answer)
Without changing the Djoser email classes and settings.py, You can override the html templates in your project's template directory using the concepts here
You just simply have to create a new folder named email in your 'templates' folder and in it create html files with the exact names for the email templates that you would want to customize/override.
For example if you want to customize the password reset email, your custom file path should resemble this :
projectName/templates/email/password_reset.html
Here is a full list of all the Djoser email templates that you can customize
I found this closed thread and it did do the job of allowing me to render out a custom template. Might want to check this
the answer from Pavlo Naumenko works for me too so thanks a lot. But just a small note: I have to change the name of the file (I couldn't use "activation.html" on my own template). If I use it, django keeps sending the default template. Don't know why.
In case someone happens that too. I was using django 3.2.3 with djoser 2.1.0
it's working! I've just changed activation.html file in
~/.local/lib/python3.5/site-packages/djoser/templates/email
without any other changes

OctoberCMS Partials sharing variables life cycle

I'm new in October CMS and I try to develop some components and these components have more than one page. I include every page as a partial in the default.htm file with an if condition depends on the type property of the page.
{% set type = __SELF__.property('type') %}
{% if type == 'y' %}
{% partial 'x::yy' %}
{% elseif type == 'x' %}
{% partial 'x::xx' %}
the problem is when I have a collection of items in one page and send id of one of the items to another ajax handler and want to retrieve full info of the item, I can't pass it to next page because of the page cycle in October CMS.for example :
// firstpage
{% set posts = __SELF__.posts %}
{%for post in posts%}
<button data-request="handlerX" data-request-data="id: {{post.id}}">
{%endfor%}
//hanlerX
public function onHanldlerX(){
$post = $this->post = POST::where('id',post("id"))->first();
return redirect()->to('/my-posts/'.$post->slug);
}
//nextpage -> my-posts/$post->slug
// post informations is unavailible
what's the best way for these type of components?
Is It the right way for this?
how can I send variables to view after the OnRun method in components?

getting route name not the route path in twig symfony

i'm developing an application with symfony3.
I want to get route name in twig. i did this :
{% set current_path = path(app.request.get('_route')) %}
{{ current_path }}
it displays the url of the current page. But i want to get route name not the path.
example :
personnel_index:
path: /liste
defaults: { _controller: "PersonnelBundle:Personnel:index" }
methods: GET
must return : personnel_index
so how can i get the route name
This is because you put the path function try like this
{% set current_path = app.request.get('_route') %}
{{ current_path }}
In the twig template, there is a global variable activeRoute.
For example {{ dump(activeRoute) }} will give you the route name.
There is one example at vendor/shopware/storefront/Resources/views/storefront/component/address/address-personal.html.twig:40
GitHub Link
With this source code.
{% if activeRoute == 'frontend.account.login.page' %}
{% set isLoginPage = true %}
{% endif %}

Simple Pyramid app: using query params for routing to edit page

I am trying to make a simple Pyramid app, and having a hell of a time figuring out what part of the syntax I'm missing. What's happening is I have an edit page for my model, and I can not figure out how to pass in the id of the entry I'm editing.
My view reads like this:
#view_config(route_name='action', match_param='action=edit', renderer='string')
def update(request):
this_id = request.matchdict.get('id', -1)
entry = Entry.by_id(this_id)
if not entry:
return HTTPNotFound()
form = EntryUpdateForm(request.POST, entry)
if request.method == 'POST' and form.validate():
form.populate_obj(entry)
return HTTPFound(location=request.route_url('blog', id=entry.id, slug=entry.slug))
return {'form': form, 'action': request.matchdict.get('action')}
I have created an edit template, it looks like this, and is working for the create page, which uses a different model:
{% extends "templates/layout.jinja2" %}
{% block body %}
<h2>Create a Journal Entry</h2>
<form action="" method="POST">
{% for field in form %}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<p>{{ field.label }}: {{ field }}</p>
{% endfor %}
<p><input type="submit" name="submit" value="Submit" /></p>
</form>
{% endblock %}
And the link I have made to the template looks like:
Edit Entry
Which yields the url http://0.0.0.0:6543/journal/edit?id=1. This is new and weird to me, because I'm used to Rails, where the url would look like http://0.0.0.0:6543/journal/1/edit but poking around and reading the Pyramid blogr tutorial, this seems like how Pyramid likes to have routes. Unfortunately, it still gives me a 404. It seems like I am successful passing the id of the entry into a query string, but somehow I am not telling the edit page to be at that location.
Thanks for any help you can give.
I can't see where the problem is as this minimal example works, if you navigate your browser to localhost:8080/journal/edit?id=723
#!/usr/bin/env python
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.config import Configurator
from waitress import serve
#view_config(route_name="root", renderer="string")
def root_view(request):
return "root_view", request.params
#view_config(route_name='action', match_param='action=edit', renderer="string")
def action_view(request):
return "action_view", request.params
if __name__ == '__main__':
config = Configurator()
config.add_route('root', '')
config.add_route('action', '/journal/{action}')
config.scan()
app = config.make_wsgi_app()
serve(app)
Maybe you have some other problem with your routes. Can you paste them here all? Are you sure you do not have another function named update in your view?
Aside from that, you are completely free to build your routes as you wish with Pyramid.
config.add_route('action2', '/different/edit/{id}')
config.add_route('action3', '/someother/{id}/edit')
I personally would rather use one of the schemes above than the match_param predicate...

Resources