I'm building a website and I'm trying to make the user able to change his credentials. I've made a form for this:
newUsername = forms.CharField(
label="Enter your new username here*",
required=True,
widget=forms.TextInput(attrs={
'class': 'userChangeCredentials',
'value': "{{ user.username }}"
}))
newEmail = forms.EmailField(
label="Enter your new e-mail adress here*",
required=True,
widget=forms.EmailInput(attrs={
'class': 'userChangeCredentials',
'value': '{{ user.email }}'
}))
newPassword = forms.CharField(
label="Enter your new password here",
required=False,
widget=forms.PasswordInput(attrs={
'class': 'userChangeCredentials',
'value': ''
}))
passwordConfirmation = forms.CharField(
label="Confirm your existing password here*",
required=True,
max_length=256,
widget=forms.PasswordInput(attrs={
'class': 'userChangeCredentials',
'value': ''
}))
The problem is, that the values in the widget dictionary are passed as raw text and I want them to be variables.
This is the resulting page layout:
Do I need to change something inside of HTML?
My HTML:
<form id="UserForm" action="{% url 'user' name=user.username %}" method="POST">
{% csrf_token %}
{{ form|safe }}
<input class="userChangeCredentials" type="submit"></input>
</form>
I tried to make the text raw like this:
widget=forms.EmailInput(attrs={
'class': 'userChangeCredentials',
'value': r'{{ user.email }}'
})
But it didn't help. I searched for a week and I couldn't find any questions of this nature. I've read the official Django form page, but there is nothing about this exact thing.
In this case, I suggest you use the form for the user credentials only (email and username), then use the built-in PasswordChangeView for updating the user password without even creating a form class for it.
As for the raw values, the best way to get them is to inherit the form from the User model.
Related
I'm creating app with authentication. My project is dockerized. When I run the server everything works fine, except
authentication.User: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
But when I want to run docker-compose exec web python3 manage.py makemigrations or docker-compose exec web python3 manage.py migrate I get an error:
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/init.py", line 176, in get_user_model
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'authentication.User' that has not been installed
I've thought it points to settings.py field AUTH_USER_MODEL, but I haven't got it.
My views.py:
def signup(request):
if request.method == "POST":
context = {'has_error': False, 'data': request.POST}
email = request.POST.get('email')
username = request.POST.get('username')
password = request.POST.get('password')
if len(password) < 6:
messages.add_message(request, messages.ERROR,
'Password should be at least 6 characters')
context['has_error'] = True
if not validate_email(email):
messages.add_message(request, messages.ERROR,
'Enter a valid email address')
context['has_error'] = True
if not username:
messages.add_message(request, messages.ERROR,
'Username is required')
context['has_error'] = True
if models.User.objects.filter(username=username).exists():
messages.add_message(request, messages.ERROR,
'Username is taken, choose another one')
context['has_error'] = True
return render(request, 'authentication/signup.html', context) # status=409
if models.User.objects.filter(email=email).exists():
messages.add_message(request, messages.ERROR,
'Email is taken, choose another one')
context['has_error'] = True
return render(request, 'authentication/signup.html', context) # status=409
if context['has_error']:
return render(request, 'authentication/signup.html', context)
user = models.User.objects.create_user(username=username, email=email)
user.set_password(password)
user.save()
return render(request, 'authentication/signup.html')
My models.py:
from django.db import models
class User(models.Model):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
username = models.CharField(
max_length=200
)
def __str__(self):
return self.email
My signup.html:
{% include "_base.html" %}
{% load static %}
{% block title %}Sign Up{% endblock title %}
{% block content %}
<link rel="stylesheet" href="{% static 'css/authentication/signup.css' %}">
<div class="container">
<form class="signup_form" method="post" action="{% url 'signup' %}">
{% csrf_token %}
<input type="text" placeholder="Email" class="input_1" name="email">
<input type="text" placeholder="Username" class="input_2" name="username">
<input type="text" placeholder="Password" class="input_3" name="password">
<button type="submit" class="submit_btn">Sign Up</button>
</form>
</div>
{% endblock content %}
_base.html is just navbar.
When I add AUTH_USER_MODEL to settings.py it results in same error.
For this you should try adding an id field in the user model like so:
from uuid import uuid4
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
Also in your user model add this to the class:
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
I advice you also change the class name form User to CustomUser to avoid clashes with internal django backend, that will be.
From:
class User(models.Model):
to:
class CustomUser(AbstractUser):
I have a problem with reload page, when I click the button wchich is used to filtrate data witch using ajax script. In condition IF not working render template .
Below sample code
Python
def viewchallenges():
categories = Categories.query.all()
if request.method=='POST':
category_id=Categories.query.filter_by(category=request.form['name']).first()
check=Challenge.query.filter_by(categorie_id=category_id.id).order_by(Challenge.timestamp.desc()).all()
if not check:
flash(_('not found'))
else:
page = request.args.get('page', 1, type=int)
posts = Challenge.query.filter_by(categorie_id=category_id.id).order_by(Challenge.timestamp.desc()).paginate(
page, current_app.config['POSTS_PER_PAGE'], False)
next_url = url_for('main.viewchallenges', page=posts.next_num) \
if posts.has_next else None
prev_url = url_for('main.viewchallenges', page=posts.prev_num) \
if posts.has_prev else None
return render_template('viewChallanges.html', title=_('View Challenge'), posts=posts.items, next_url=next_url, prev_url=prev_url,categories=categories)
page = request.args.get('page', 1, type=int)
posts =Challenge.query.order_by(Challenge.timestamp.desc()).paginate(
page,current_app.config['POSTS_PER_PAGE'], False)
next_url = url_for('main.viewchallenges', page=posts.next_num) \
if posts.has_next else None
prev_url = url_for('main.viewchallenges', page=posts.prev_num) \
if posts.has_prev else None
return render_template('viewChallanges.html', title=_('View Challenge'), posts=posts.items, next_url=next_url, prev_url=prev_url,categories=categories)
HTML
{% for item_category in categories %}
<button class="btn btn-secondary fby_category">{{item_category.category}}</button>
{% endfor %}
AJAX
$('.fby_category').click(function(e) {
var url = "{{ url_for('main.viewchallenges') }}";
e.preventDefault();
$.ajax({
type: "POST",
url: url,
data: {
'name': $(this).text()
},
});
});
You want to render a new template. It means that the user is going to get a new webpage. Then you do not need Javascript here. You can just create multiple forms
{% for item_category in categories %}
<form action="{{ url_for('main.viewchallenges') }}" method="post">
<input type="submit" name="{{item_category.category}}<" value="
{{item_category.category}}" />
{% endfor %}
</form>
Easier, isn't ?
Because I am not from English Naive country.
Default html content from Django form, is not suitable for my country.
Could someone tell me how to edit html content in forms.py?
I just want to keep English variable for later SQL column settings, but change html content in form.
in forms.py
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = DjUser
fields = ('username', 'email', 'password')
in html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" value="註冊">
</form>
It showed all English content in html, like Username, Email Address etc..
The thing I needed is 使用者名稱, 電子信箱 etc.. The html contents I want to edit:
You can use attr for styling and naming you're form fields, it will go something like this:
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'my-class',
'placeholder': '使用者名稱, 電子信箱',
}))
also you will perhaps need to do some localization for you're application.
I made a basic Django form and implemented that into my HTML. In my views.py, I am trying to send an email out, and I know even if I can't send the email, I should still see a successful POST submission and email detail in terminal. However, the page simply refreshes and nothing happens.
views.py snippet:
def ticket(request, room_name):
form_class = TicketForm
if request.method == 'GET':
form = TicketForm()
else:
form = TicketForm(request.POST)
# validating and cleaning data
if form.is_valid():
type_of_issue = form.cleaned_data['type_of_issue']
#a lot of fields are cleaned, irrelevant to question
try:
send_mail("Issue/Feedback for Room " + room_name, message, from_email, ['admin#example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found')
return redirect('index') #index is my homepage separate from my form/ticket page
return render(request, 'ticket.html', context={'room_name': room_name, 'room': room, 'form': form_class, })
ticket.html (where my form is located) snippet:
<form id="ticket-border" class="" method="post">
{% csrf_token %}
<!--a lot of form data goes here, irrelevant to question-->
<input type="submit" value="Submit">
</form>
settings.py snippet that has to do with sending email
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'example#gmail.com'
EMAIL_HOST_PASSWORD = 'notmyrealpassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
I've looked at many examples and YouTube videos online, but I seem to be missing why nothing shows up on my console after submitting. The page simply refreshes after hitting submit. It shouldn't be going into my if == GET statement, but I checked that it isn't by changing the criteria and sending it somewhere else, which it didn't do.
Can a fresh pair of eyes help me see the problem?
Edit: Forgot to add, I've also tried adding either
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
or
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
into my settings.py, but it makes no difference. The page still refreshes and nothing shows up in my console or inbox.
Added TicketForm upon request:
class TicketForm(forms.Form):
type_of_issue = forms.ChoiceField(
choices=ISSUE_CHOICES, widget=forms.RadioSelect(), required=True)
first_name = forms.CharField(required=False, widget=forms.TextInput(attrs={
'class': 'form-control', 'id': 'first-name', 'type': 'text', 'name': 'first-name', 'maxlength': '50', 'placeholder': 'First name'}))
last_name = forms.CharField(required=False, widget=forms.TextInput(attrs={
'class': 'form-control', 'id': 'last-name', 'type': 'text', 'name': 'last-name', 'maxlength': '50', 'placeholder': 'Last name'}))
email_address = forms.EmailField(required=False, widget=forms.EmailInput(
attrs={'class': 'form-control', 'type': 'email', 'id': 'email', 'name': 'email', 'placeholder': 'Email address'}))
feedback_or_further_details = forms.CharField(
required=True, widget=forms.Textarea(attrs={'class': 'form-control', 'rows': '5', 'name': 'additional-details', 'placeholder': 'Please enter additional details or your feedback here.'}))
affiliation = forms.ChoiceField(
choices=AFFILIATION_CHOICES, widget=forms.CheckboxSelectMultiple(), required=True)
I really hope you can help me with this. I am having trouble showing the ID population the textbox when I modify the form.
Let me explain it to you in detail
This is my list:
myList = [{ 'id':100, 'name': 'test mission 1' },
{ 'id':102, 'name': 'test mission 2' },
{ 'id':103, 'name': 'test mission 3' },
{ 'id':104, 'name': 'test mission 4' },]
This is my HTML with a workable typeahead function.
<input type="text"
ng-model="selected"
typeahead="mission as mission.name for mission in myList | filter:{name:$viewValue} | limitTo:8"
name="mission_name"
disabled>
<input type="hidden"
name="mission_id"
ng-model="selected"
value="{{field.value}}">
so whatever name value you type from the textbox naming mission_name, the id of that name will automatically populate the textbox naming mission_id. This is already workable and this is not the real problem. Because the only value that I want to save to the database is the mission_id. Let me show you my controller first.
This is my controller
angular.module('actinbox.web').controller('TypeaheadCtrl_{{ field.id_for_label }}', function($scope) {
$scope.selected = "{{ mission.name }}";
$scope.myList = {{ Mission|safe }};
});
The problem is, when I want to modify this data and i go to the form, I can only see that mission_name is populated by the data, it must be because i put an initial value such as $scope.selected = "{{ mission.name }}". However in mission_id textbox, the initial value is also the same as the value of mission_name maybe bacause of ng-model. What I want to do is to see the mission_id value and not the mission_name value.
I hope my explanation is clear. I really need help to this.
Try chaning this
<input type="hidden"
name="mission_id"
ng-model="selected"
value="{{field.value}}">
to
<input type="hidden"
name="mission_id"
ng-model="selected1"
value="{{field.value}}">
Then in js
$scope.selected = "{{ mission.name }}";
$scope.selected1 = "{{ mission.id }}";
$scope.myList = {{ Mission|safe }};