I am using the Django authentication system and have another model which is about user:
class user(models.Model):
user = models.OneToOneField(User)
user_code=models.IntegerField(max_length=3)
phone=models.IntegerField(max_length=10)
task=models.ForeignKey(task)
class Meta:
unique_together = ('user_code', 'task')
def __unicode__(self):
return str(self.user_code)
so I made two forms for user registeration(form.py):
class userForm(forms.ModelForm):
class Meta:
model=User
widgets = {'password': forms.PasswordInput(),}
class Form4(forms.ModelForm):
class Meta:
model=user
Now in my view I want to send two forms to template and submit both of them. Everything is well but after submitting I can't check form validation? this is my view:
def add_new_user(request):
if request.method == 'POST': # If the form has been submitted...
user_form = userForm(request.POST) # django User
form = Form4(request.POST) # my model user
if user_form.is_valid() and form.is_valid(): # All validation rules pass **edited** is_valide
user_name=user_form.cleaned_data['username']
password = user_form.cleaned_data['password']
name=user_form.cleaned_data['first_name']
user_id = form.cleaned_data['user_code']
email = user_form.cleaned_data['email']
phone = form.cleaned_data['phone']
task = form.cleaned_data['task']
else: # **added** form invalid statement
return render(request, 'student/form4.html', {'form': form,'user_form':user_form})
try: #**moved from valid statement**
do somthing...
except ValueError :
do somthing...
else:
form = Form4()
user_form=userForm()
# An unbound form
return render(request, 'student/form4.html', {'form': form,'user_form':user_form})
this is my template(form4.html):
<form name="myForm" action="{% url 'student:add_new_user' %}" onsubmit="return validateForm4();" method="post">
{% csrf_token %}
<div id="form-data">
{{ form.non_field_errors }}
{{ user_form.username }}{{ user_form.username.errors }}
<label for="id_user_name">user name:</label><br>
{{ user_form.password }}{{ user_form.password.errors }}
<label for="id_password">password:</label><br>
{{ user_form.first_name }}{{ user_form.first_name.errors }}
<label for="id_name">first name:</label><br>
{{ user_form.email }}{{ user_form.email.errors }}
<label for="id_email">email:</label><br>
{{ form.user_code }}{{ form.user_code.errors }}
<label for="id_email">use ID:</label><br>
{{ form.phone }}{{ form.phone.errors }}
<label for="id_phone">phone number:</label><br>
{{ form.task }}{{ form.task.errors }}
<label for="id_task">task:</label><br>
<input type="submit" value="register" /><br>
</div>
</form>
But it returns False for both validation. How can I check validation?
ANSWER:
I add which field I want from User and user. and change my "form.py" to :
class userForm(forms.ModelForm):
class Meta:
model=User
fields = ('username', 'password','first_name','email' )
widgets = {'password': forms.PasswordInput(),}
class Form4(forms.ModelForm):
class Meta:
model=user
fields = ('user_code', 'phone','task' )
thanks for all comments and answer.
Try add different prefixes to each of forms
# GET
user_form = userForm(prefix="one")
form = Form4(prefix="two")
# POST
user_form = userForm(request.POST, prefix="one")
form = Form4(request.POST, prefix="two")
Related
In my django project I have a form VisitorRegForm which collects scanned_id and body_temp and submits data to my database table ClinicalData, since the current user is already logged in, how can I make this form to also be able grab current logged in user's username and email (Note: username and email were both created from the built-in django User model) and submit these four items: 'scanned_id', 'body_temp', 'username', 'email' into the database table ClinicalData?
Don't mind the missing details and inports, the form works and am able to submit 'scanned_id', 'body_temp'. Help me on the easiest way I will be able to submit these four items: 'scanned_id', 'body_temp', 'username', 'email' looking at the details shown in the files below:
Where should it be easier to achieve this; in the views.py or the template file?
forms.py
class VisitorRegForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class ScannerForm(ModelForm):
class Meta:
model = ClinicalData
fields = ['scanned_id', 'body_temp']
models.py
class ClinicalData(models.Model):
...
scanned_id = models.CharField(verbose_name="Scanned ID", max_length=50, null=True)
body_temp = models.DecimalField(verbose_name="Body Temperature", max_digits=3, decimal_places=1, null=True)
username = models.CharField(verbose_name="Facility Name", max_length=200, null=True)
email = models.EmailField(verbose_name="Visitor Email", max_length=200, null=True)
...
views.py
Am assuming I might need like two variables here in the views that should help me like the ones i've commented out, if it should start from here, help me how it should succeed:
#login_required(login_url='login')
def scanEnter(request):
#grab_username = function_to_grab_current_logged_in_username_HELP_ME_HERE
#grab_email = function_to_grab_current_logged_in_user_email_HELP_ME_HERE
form = ScannerForm(request.POST)
if request.method == 'POST':
form = ScannerForm(request.POST)
if form.is_valid():
form.save()
return redirect('scanenter')
context = {'form': form}
return render(request, 'scan_enter_fac.html', context)
scan_enter_fac.html
<form action="" method="post">
{% csrf_token %}
<div class="">scanned_id<input type="text" id="multiple" class="form-control" placeholder="or Type ID here; e.g: ACCTS-147" name="scanned_id"></div>
<div class="">body_temp<input type="text" class="form-control" placeholder="e.g: 36.5" name="body_temp"></div>
<button type="submit" class="btn btn-danger btn-block">Submit</button>
</form>
views.py:
#login_required(login_url='login')
def scanEnter(request):
#grab_username = function_to_grab_current_logged_in_username_HELP_ME_HERE
#grab_email = function_to_grab_current_logged_in_user_email_HELP_ME_HERE
form = ScannerForm(request.POST)
if request.method == 'POST':
form = ScannerForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.username = request.user.username #new
form.email = request.user.email #new
form.save()
return redirect('scanenter')
context = {'form': form}
return render(request, 'scan_enter_fac.html', context)
scan_enter_fac.html
<form action="" method="post">
{% csrf_token %}
<div class="">{{ form.scanned_id }}</div>
<div class="">{{ form.body_temp }}</div>
<button type="submit" class="btn btn-danger btn-block">Submit</button>
</form>
I am making a form in which the user can edit their profile, so currentley I have 2 forms, one that edits the User model(first_name, Username and Email) and other one that edits the Profile model(biography). The problem is that everytime I edit, just the User model is the one that gets saved while the Profile model doesnt. I think that the error is on the views.py file.
views.py
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
form1 = UpdateProfileForm(request.POST, instance=request.user)
if form.is_valid:
form.save()
form1.save()
return redirect('profile')
else:
form = EditProfileForm(instance=request.user)
form1 = UpdateProfileForm(instance=request.user)
args = {
'form': form,
'form1': form1,
}
return render(request, 'profile-edit.html', args)
forms.py
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields = (
'first_name',
'username',
'email',
)
exclude = ('password',)
class UpdateProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'bio',
'profile_pic',
)
exclude = ('user',)
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.CharField(max_length=400, default=1)
def __str__(self):
return f'{self.user.username} Profile'
profile-edit.html (I replaced the {{form.as_p}} and {{ form1.as_p }} to the following html code)
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="edit-profile">
<h3>Name</h3>
<input type="text" name="first_name" value="{{ user.first_name }}" maxlength="30" id="id_first_name">
<h3>Username</h3>
<input type="text" name="username" value="{{ user.username }}" maxlength="150" required="" id="id_username">
<h3>Bio</h3>
<input type="text" name="bio" value="{{ user.profile.bio }}" maxlength="400" id="id_bio">
<h3>Email</h3>
<input type="email" name="email" value="{{ user.email }}" maxlength="254" id="id_email">
<button type="submit">Submit</button>
</div>
</form>
I found the error on my code, i missed to pass the .profile from the model in the views.py file
Bad
form1 = UpdateProfileForm(request.POST, instance=request.user)
Good
form1 = UpdateProfileForm(request.POST, instance=request.user.profile)
I'm trying to get a list of objects in Django from a model.
I just want to get the list of 'dht node' from the request user, but it shows nothing in the html file (as if the list was empty). The user that I'm using has 2 'dht nodes' and they're shown in the django admin.
I don't know what is wrong, because if I use the instruction "member.dht.create(...)" in the views function and a create a new 'dht node' like this, this is shown. Only 'dht nodes' that I enter by form do not show. Can be the form?
Thanks a lot, Here's my code:
Models.py
class Node(models.Model):
name = models.CharField(primary_key=True, null=False, max_length= 50)
description= models.CharField(default=None, null=False, max_length= 250)
topic=models.CharField(default=None, null=False, max_length= 50, unique=True)
def __unicode__(self):
return self.name
class dht(Node):
temp = models.IntegerField(default=None, null=True)
hum = models.IntegerField(default=None, null=True)
class UserProfile(User):
uid = models.CharField(default=None, null=False, max_length= 250)
dht = models.ManyToManyField(dht, blank=True)
def __unicode__(self):
return self.user.username
Views.py -dht list-
#login_required(login_url = '/web/login')
def listDhtSensor(request):
member = request.user.userprofile
list = member.dht.all()
return render(request, 'web/listDhtSensor.html', {'list':list})
Html -listDhtSensor.html-
{% block content %}
{% for dht in list %}
{{ dht.name }}
{{ dht.topic }}
{% endfor %}
{% endblock %}
Forms.py
class newDHTSensorForm(forms.ModelForm):
class Meta:
model = dht
field = ['name',
'description',
'topic',]
labels = {'name': 'Name' ,
'description': 'Description',
'topic': 'Topic',}
exclude = ['temp', 'hum']
Views.py -dht form-
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Html -newDhtSensor.html-
{% block content %}
<div class="boxReg">
<form method="post">
{% csrf_token %}
<h2>{{ form.name.errors.as_text }}</h2>
<p><label for="id_name">Name:</label> <input class="barraForm" type="text" name="name" maxlength="150" autofocus="" required="" id="id_name"></p>
<p><label for="id_description">Description:</label> <input class="barraForm" type="text" name="description" maxlength="150" id="id_description"></p>
<h2>{{ form.topic.errors.as_text }}</h2>
<p><label for="id_topic">Topic:</label> <input class="barraForm" type="text" name="topic" maxlength="254" id="id_topic"></p>
<div class="boxButtonReg">
<button class="buttonReg" type="submit">Save</button>
</div>
</form>
</div>
{% endblock %}
It shows nothing because you did not link you dht objects to that UserProfile, so if you later query for the dhts for that UserProfile, evidently the list is empty. You should add it to the dht relation, like:
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save()
request.user.userprofile.dht.add(post)
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Note that you first need to save the post, so you should omit the commit=False aprameter.
I have read in Django documentation that the clean() method of ModelForm validates the unique_together constraint on my model, and raises a ValidationError if it is not validated. However my ModelForm doesn't do this. At least it doesn't give an error message in the form, instead I get a Django error and traceback:
ValueError at / The Jelentkezes could not be created because the data didn't validate.
This is not because I have excluded one of the fields of the unique_together constraint. Other validations of the form work, they give error messages on the form. Please help, thank you!
I use Django 1.10 and Python is 3.5.
I have created the following models in models.py:
from django.db import models
class FoglalkozasTipus(models.Model):
foglalkozas_tipusa = models.CharField(max_length=255, unique=True)
def __str__(self):
return '%s' % (self.foglalkozas_tipusa)
class Foglalkozas(models.Model):
kezdet = models.DateTimeField()
veg = models.DateTimeField()
foglalkozas_tipusa = models.ForeignKey(FoglalkozasTipus,
on_delete=models.CASCADE)
class Meta:
unique_together = (("kezdet", "veg"),)
ordering = ['kezdet', 'veg']
def __str__(self):
return '%s-%s %s' % (self.kezdet.strftime("%Y.%m.%d %H:%M"),
self.veg.strftime("%H:%M"), self.foglalkozas_tipusa)
class Jelentkezes(models.Model):
foglalkozas = models.ForeignKey(Foglalkozas, on_delete=models.CASCADE)
email = models.EmailField()
vezeteknev = models.CharField(max_length=255)
keresztnev = models.CharField(max_length=255)
class Meta:
unique_together = (("foglalkozas", "email"),)
def __str__(self):
return '%s: %s %s (%s)' % (self.foglalkozas, self.vezeteknev,
self.keresztnev, self.email)
For model Jelentkezes I have created a ModelForm in forms.py:
from django.utils import timezone
from django.forms import ModelForm, RadioSelect
from .models import Jelentkezes, Foglalkozas
class JelentkezesForm(ModelForm):
class Meta:
model = Jelentkezes
fields = ['foglalkozas', 'email', 'vezeteknev', 'keresztnev']
widgets = {
'foglalkozas': RadioSelect,
}
def __init__(self, *args, **kwargs):
super(JelentkezesForm, self).__init__(*args, **kwargs)
self.fields['foglalkozas'].queryset =
Foglalkozas.objects.filter(kezdet__gt=timezone.now())
self.fields['foglalkozas'].empty_label = None
In views.py I use this ModelForm:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import JelentkezesForm
def index(request):
if request.method == 'POST':
form = JelentkezesForm(request.POST)
form.save()
return HttpResponseRedirect('koszonet/')
else:
form = JelentkezesForm()
return render(request, 'aviva/index.html', {'form': form})
In index.html the form looks like this (I use W3.CSS framework and django-widget-tweaks for styling):
{% load widget_tweaks %}
<form action="" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.foglalkozas.errors }}
<label class="w3-label" for="{{ form.foglalkozas.id_for_label }}"><b>{{ form.foglalkozas.label }}:</b></label>
{% for radio in form.foglalkozas %}
<div class="w3-radio">
{{ radio }}
</div>
{% endfor %}
{{ form.email.errors }}
<label class="w3-label" for="{{ form.email.id_for_label }}"><b>{{ form.email.label }}:</b></label>
{{ form.email|add_class:"w3-input w3-border w3-round" }}
{{ form.vezeteknev.errors }}
<label class="w3-label" for="{{ form.vezeteknev.id_for_label }}"><b>{{ form.vezeteknev.label }}:</b></label>
{{ form.vezeteknev|add_class:"w3-input w3-border w3-round" }}
{{ form.keresztnev.errors }}
<label class="w3-label" for="{{ form.keresztnev.id_for_label }}"><b>{{ form.keresztnev.label }}:</b></label>
{{ form.keresztnev|add_class:"w3-input w3-border w3-round" }}
<p><input type="submit" class="w3-btn w3-blue w3-left w3-border" value="Jelentkezés elküldése" />
<button type="reset" class="w3-btn w3-yellow w3-right w3-border" value="Reset">Űrlapadatok törlése</button></p>
</form>
You never call the validation on your form. It should be:
if request.method == 'POST':
form = JelentkezesForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('koszonet/')
When I submitted forms (but on page I filled id more than 1 form) - my FormSet saves the data of only one form, the rest of the data just disappear...
My template:
<div id="data">
<form method="post" action="/lookup/" id="test_data">{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<section id="test_data_row">
{{ form }}
</section>
{% endfor %}
</form>
</div>
<div class="bt">
<button type="submit" class="btn btn-default" id="submit_form" form="test_data">Submit</button>
<button type="button" class="btn btn-default" id="add" value="Add row"/>Add row</button>
</div>
My forms.py:
class LookupForm(forms.ModelForm):
class Meta:
model = look
exclude = ()
LookupFormSet = formset_factory(LookupForm, can_delete=True)
My model
class look(models.Model):
class Meta():
db_table = 'lookup'
id_device = models.CharField(max_length=75)
phone_number = models.CharField(max_length=100)
phone_number_country = models.CharField(max_length=1000)
text = models.CharField(max_length=1000, default=None)
my views.py:
def manage_articles(request):
LookupFormSet = modelformset_factory(model=look, exclude=())
if request.method == "POST":
formset = LookupFormSet(
request.POST, request.FILES,
queryset=look.objects.none(),
)
if formset.is_valid():
for form in formset:
form.save()
return HttpResponseRedirect('/')
else:
formset = LookupFormSet(queryset=look.objects.none())
return render(request, 'req/lookup.html', {'formset': formset})
my JS (js for add new form):
document.getElementById('add').onclick = duplicate;
var i = 0;
var original = document.getElementById('test_data');
function duplicate() {
var clone = original.cloneNode(true); // "deep" clone
clone.id = "test_data" + ++i; // there can only be one element with an ID
original.parentNode.appendChild(clone);
}
You cannot save a formset as it contains multiple forms. So I would suggest you change your code to:
if formset.is_valid():
for form in formset:
form.save()
return HttpResponseRedirect('/')
See the docs.