form validation with django CBV FormView - django

Can someone explain me how can I validate my form, it's rather simple stuff and some how I can I just don't get it, need to validate my select field so I can return and display data, can someone explain how to do this
from django import forms
from statistics.choices import MONTH_CHOICES
class StatisticsForm(forms.Form):
invoice_year = forms.CharField(max_length=255, required=False,
widget=forms.TextInput(attrs={'placeholder': 'Search Year'}))
month_choice = forms.ChoiceField(choices=MONTH_CHOICES)

from django import forms
from statistics.choices import MONTH_CHOICES
class StatisticsForm(forms.Form):
invoice_year = forms.CharField(max_length=255, required=False,
widget=forms.TextInput(attrs={'placeholder': 'Search Year'}))
month_choice = forms.ChoiceField(choices=MONTH_CHOICES)
def clean_invoice_year(self):
invoice_year_val = self.cleaned_data.get('invoice_year')
if condition_not_satisfied:
raise forms.ValidationError('Invalid invoice year')
return invoice_year_val

Related

How to save signed in username with the form to database? Django

All other data is saved ideally but as shown below, the user id part shows as a pull down bar and a null value which should be a signed-in username.
What's wrong with my code?
The database page
Here's my code.
views.py
from .models import Markers
from .forms import AddMarkersInfo
from django.http import HttpResponse
def addinfo(request):
if request.method == 'POST':
mks = AddMarkersInfo(request.POST)
if mks.is_valid():
submit = mks.save(commit=False)
submit.user = request.user
submit.save()
name = mks.cleaned_data['name']
address = mks.cleaned_data['address']
description = mks.cleaned_data['description']
type = mks.cleaned_data['type']
lat = mks.cleaned_data['lat']
lng = mks.cleaned_data['lng']
Markers.objects.get_or_create(name=name, address=address, description=description, type=type, lat=lat, lng=lng)
return render(request, 'home.html', {'mks': mks })
else:
mks = AddMarkersInfo()
return render(request, 'home.html', {'mks': mks})
models.py
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.contrib.auth import get_user_model
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class Markers(models.Model):
User = settings.AUTH_USER_MODEL
use_id= models.ForeignKey(User, null=True, on_delete=models.SET(get_sentinel_user),)
name = models.CharField(max_length=60,default = 'name')
address = models.CharField(max_length=100,default = 'address')
description = models.CharField(max_length=150, default='description')
types = (
('m', 'museum'),
('s', 'school'),
('r', 'restaurant'),
('o', 'other'),
)
type = models.CharField(max_length=60, choices=types, default='museum')
lat = models.IntegerField()
lng = models.IntegerField()
forms.py
from django import forms
from maps.models import Markers
class AddMarkersInfo(forms.ModelForm):
class Meta:
model = Markers
fields = ['name','address','description', 'type','lat','lng',]
Well, first of all, you should remove the lines from django.contrib.auth.models import User and User = settings.AUTH_USER_MODEL in models.py if you are going to use settings.AUTH_USER_MODEL. You should use only one of the two.
And you can change your field to:
use_id= models.ForeignKey(settings.AUTH_USER_MODEL, ...
Secondly, it seems like you are duplicating the creation. The lines
submit = mks.save(commit=False)
submit.user = request.user
submit.save()
already create an Markers instance, so there is no need to call Markers.objects.get_or_create(... after that.
And, according to you models, the field should be submit.use_id instead of submit.user.
Now, if I understand your question correctly you want to make the use_id field read-only in your form/template.
I don't know why that field is even showing up in your form, since it is not listed in your forms Meta.fields.
You could try something like setting the widget attribute readonly:
class AddMarkersInfo(forms.ModelForm):
class Meta:
model = Markers
fields = ['use_id', 'name', 'address', 'description', 'type', 'lat', 'lng']
widgets = {
'use_id': forms.Textarea(attrs={'readonly': 'readonly'}),
}

Django: text-input instead selection on foreignkey

I want to create a messaging function in ma django app. User should be able to write other users a textmessage.
models.py
from django.contrib.auth.models import User
class Message(models.Model):
recipient = models.ForeignKey(User, null=True)
contentDescription = models.CharField(max_length=1000, null=True)
By default, with no forms.py entry I get a selection, which will be unuseful with many users. I want the message sender to type in the user name, or in the first step the user id (which I could resolve with ajax from the name) .
Integer
But with forms.py
recipient = forms.IntegerField( widget=forms.NumberInput , required=False,)
I get:
Cannot assign "11": "Transport.recipient" must be a "User" instance.
ChoiceField and NumberInput
with:
recipient = forms.ChoiceField( widget=forms.NumberInput, required=False,)
I get the error message "not valid"
Is it possible to write the foreignkey 'manually' at all?
Try this:
recipient = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.Select, required=False)
considering your
models.py -
from django.contrib.auth.models import User
class Message(models.Model):
recipient = models.ManytoMany(User, null=True)
contentDescription = models.TextField()
forms.py
from .models import Message
from django import forms
from django.contrib.auth.models import User
class MailForm(forms.ModelForm):
recipient = forms.Charfield()
class Meta:
model = Message
fields = ('contentDescription',)
def clean_recipient(self):
user_list = self.cleaned_data.get('recipient')
# considering you post user_list of usernames as 'username1,username2,username3'
if user_list is not None:
user_list = user_list.split(',')
user_qs = User.objects.filter(username__in=userlist)
else:
raise forms.ValidationError('Error in this field')
return user_qs
def save(self, user_qs):
self.instance.user = user_qs
return super().save()
in views.py -
from .forms import MailForm
def your_view(request):
form = MailForm(request.POST or None)
if form.is_valid():
user_qs=form.cleaned_data.get('recipient')
form.save(user_qs)
#return render here
else:
#create your context here and return render
This is not perfect but can give you an idea how to implement. With the details you gave this is the best I can do for now.

django admin form won't be modify

from django import forms
from .models import SignUp
class forml(forms.ModelForm):
class Meta:
model = SignUp
fields = ['Email', 'Name']
# exclude =['sam']
def clean_email(self):
email = self.cleaned_data.get('Email')
email_base, ext = email.split("#")
exname, domain = ext.split(".")
if not domain == "gov":
raise forms.ValidationError("plz write .gov")
return email
here i'm trying to force the user to sign up with .gov email but for a reason that i can't know it's doing the work !
Your problem is with the uppercase field names.
have you tried calling def clean_Email(self): ???
Also, consider having all your fields lowercase. In python, only class name should be Camelcase.
Hope it helps.

Django PasswordInput

I'm using PasswordInput, for an attribute that is optional.
models.py
password = models.CharField(_('Site Password'), max_length=128,
blank=True, null=True)
forms.py
from django.forms import PasswordInput
...
class Meta:
model = ...
widgets = {
'password': PasswordInput(),
}
Which works as expected. However using this widget means there is no way to clear this input, once the password has been set once!
I was hoping to have something like the AdminFileWidget, where there is an option to clear the image/file by selecting the 'clear' checkbox.
Other option is to add an additional 'clear_password' field to the ModelForm.
clear_password = forms.BooleanField(label=_('Clear'), initial=False,
required=False)
And clear the password on save method:
def save(self, commit=True):
...
if self.cleaned_data['clear_password']:
obj.password = None
else:
# Save the provided password in hashed format
obj.password = make_password(self.cleaned_data['password'])
And this works too. But I was hoping a more cleaner solution ..
I had a look at django.forms.widgets.ClearableFileInput .. but it's way too complex for a newbie like me :-(.
Any help will be appreciated. Many Thanks
You could clear the value of the form by passing a null value to the value attribute.
Something like that :
from django.forms import PasswordInput
from models import YourModel
password = forms.PasswordInput(attrs={'value': ''})
class Meta:
model = YourModel

How to create password input field in django

Hi I am using the django model class with some field and a password field. Instead of displaying regular plain text I want to display password input. I created a model class like this:
class UserForm(ModelForm):
class Meta:
password = forms.CharField(widget=forms.PasswordInput)
model = User
widgets = {
'password': forms.PasswordInput(),
}
But i am getting the following error: NameError: name 'forms' is not defined.
I am using django version 1.4.0. I followed this link : Django password problems
Still getting the same error. What should i do. Where am i getting wrong.Please help
The widget needs to be a function call, not a property. You were missing parenthesis.
class UserForm(ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
You need to include the following in your imports;
from django import forms
Why not just create your own password field that you can use in all your models.
from django import forms
class PasswordField(forms.CharField):
widget = forms.PasswordInput
class PasswordModelField(models.CharField):
def formfield(self, **kwargs):
defaults = {'form_class': PasswordField}
defaults.update(kwargs)
return super(PasswordModelField, self).formfield(**defaults)
So now in your model you use
password = PasswordModelField()
#DrTyrsa is correct. Don't forget your parentheses.
from django.forms import CharField, Form, PasswordInput
class UserForm(Form):
password = CharField(widget=PasswordInput())
I did as a follow without any extra import
from django import forms
class Loginform(forms.Form):
attrs = {
"type": "password"
}
password = forms.CharField(widget=forms.TextInput(attrs=attrs))
The idea comes form source code:
https://docs.djangoproject.com/en/2.0/_modules/django/forms/fields/#CharField
Since this question was asked a couple years ago, and it is well indexed on search results, this answer might help some people coming here with the same problem but be using a more recent Django version.
I'm using Django 1.11 but it should work for Django 2.0 as well.
Taking into account that you using a model user I will assume that you are using the default User() model from Django.
Since the User() model already has a password field, we can just add a widget to it.
from django import forms
from django.contrib.auth.models import User
# also, it will work with a custom user model if needed.
# from .models import User
class UserRegistrationForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'password']
widgets = {
# telling Django your password field in the mode is a password input on the template
'password': forms.PasswordInput()
}
Check the docs
I'm fairly new to Django, if my answer was not accurate enough, please let us know, I'd be happy to edit it later on.
** Try to use this **
password1 = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'input-text with-border', 'placeholder': 'Password'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'input-text with-border', 'placeholder': 'Repeat Password'}))
It's very simple.
You should get password form field out of Meta class.
What was written by the OP at password = forms.Charfield(widget=forms.PasswordInput) was correct. It just does not belong in the class Meta: section. Instead, it should be above it, indented one level below class UserForm....
The solutions above works if the field is nullable. Using render_value will render the password into the input field and show the value as asterix placeholders.
Attention: This is great if you simply want to hide the password from users, but the password will be readable by using javascript.
class UserForm(forms.ModelForm):
class Meta:
model = Org
fields = '__all__'
widgets = {
'password': forms.PasswordInput(render_value=True),
}
Edit:
Found a better solution without exposing the current password.
PASSWORD_ASTERIX_PLACEHOLDER will be set as value when loading the input. Before saving the model, it reverts the value to the old one if a user is not setting an explicit new password.
FormInput:
class PrefilledPasswordInput(PasswordInput):
PASSWORD_ASTERIX_PLACEHOLDER: str = 'hidden-password'
def __init__(self, attrs: dict = None, *args, **kwargs):
if not attrs:
attrs = {}
attrs.setdefault('value', PrefilledPasswordInput.PASSWORD_ASTERIX_PLACEHOLDER)
super().__init__(attrs=attrs, *args, **kwargs)
ModelField:
class PasswordCharField(models.CharField):
def to_python(self, value):
return super().to_python(value)
def pre_save(self, model_instance, add):
attr_name = self.get_attname()
if not add:
# Reset to old value if matching with PASSWORD_ASTERIX_PLACEHOLDER
old_instance = self.model.objects.get(id=model_instance.id)
current_value: str = getattr(model_instance, attr_name)
if current_value == PrefilledPasswordInput.PASSWORD_ASTERIX_PLACEHOLDER:
old_value: str = getattr(old_instance, attr_name)
setattr(model_instance, attr_name, old_value)
return super().pre_save(model_instance, add)
Your admin-(form):
class UserForm(forms.ModelForm):
class Meta:
model = Org
fields = '__all__'
widgets = {
'password': PrefilledPasswordInput(),
}
Your model:
class User(SomeBaseModel):
...
password = PasswordCharField(max_length=32, null=False, blank=False)
from django import forms
class loginForm(forms.Form):
username = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Your userName'}))
password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'please enter password'}))