Saving data from a form submission - python

I want to create an account registration page that links directly to an account info page and displays the account info. I'm having a hard time getting the form to save the account info into my model and I don't know why.
models.py:
class Owner(models.Model):
fullname = models.CharField(max_length=255)
username = models.CharField(max_length=255)
password = models.CharField(max_length=255)
email = models.EmailField()
def __unicode__(self):
return self.fullname
""" This is a Form class and not a regular Model class """
class OwnerForm(forms.Form):
class Meta:
model = Owner
fields = ['fullname', 'username', 'password', 'email']
views.py:
def register(request):
form = OwnerForm()
if request.POST:
form = OwnerForm(request.POST)
if form.is_valid():
fullname = request.POST.get('fullname', '')
username = request.POST.get('username', '')
password = request.POST.get('password', '')
email = request.POST.get('email', '')
owner_obj = Owner(fullame=fullname, username=username, password=password, email=email)
owner_obj.save()
return HttpResponseRedirect('courses/accountinfo.html')
else:
form = OwnerForm()
return render_to_response('courses/register.html', {'form': form}, context_instance=RequestContext(request))
register.html:
{% extends "layout.html" %}
{% load static from staticfiles %}
{% block title %}{{ page.title }}{% endblock %}
{% block content %}
<article>
<div id="Register">
<form action="{% url 'courses:accountinfo' %}" method="post"> {% csrf_token %}
<p>
<label for="fullname">Full name:</label>
<input id="fullname" name="fullname" type="text">
</p>
<p>
<label for="email">Email</label>
<input id="email" name="email" type="text">
</p>
<p>
<label for="username">Username</label>
<input id="username" name="username" type="text">
</p>
<p>
<label for="password">Password</label>
<input id="password" name="password" type="password">
<span>Enter a password longer than 8 characters</span>
</p>
<p>
<label for="confirm_password">Confirm Password</label>
<input id="confirm_password" name="confirm_password" type="password">
<span>Please confirm your password</span>
</p>
<p>
<input type="submit" value="REGISTER" id="submit">
</p>
</form>
<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'js/app.js' %}" charset="utf-8"></script>
</div>
</article>
{% endblock %}

You can call this after checking if the form.is_valid, then send the redirect and let your other view handle the rest. The issue may also be with the accountinfo view, but you didn't post that code.
owner = form.save()
owner.set_password(owner.password)
owner.save()

Use the save method on the form to save the data rather than creating a model object once the form is valid. However I see that the template contains additional fields. Do you have something in the valid method?
What is the error that you are getting? are you posting to the correct url?

Related

How do I save form response as an object in Django's database?

I am unable to save my form responses to the database as an object in Django.
Everytime I click on submit to submit my form, I am just logged out of my website and the object isnt saved in the database either.
Can anyone tell me where I am going wrong?
This is my models in models.py.
class Chain(models.Model):
name = models.CharField(max_length=255)
user = models.ForeignKey(User, on_delete=models.CASCADE)
year = models.CharField(max_length=10, default="20XX")
sem = models.CharField(max_length=30, default="Default Semester")
code = models.CharField(max_length=10, default="SUB-CODE")
slot = models.CharField(max_length=10, default="EX+EX")
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
This is my view in views.py file.
#login_required(login_url='/')
def create_course(request):
if request.method == 'GET':
return render(request, 'create_course.html', {})
elif request.method == 'POST':
name=request.POST['name']
year=request.POST['year']
sem=request.POST['sem']
code=request.POST['code']
slot=request.POST['slot']
newchain = Chain(
name=name,
year=year,
sem=sem,
code=code,
slot=slot,
)
newchain.user = request.user
newchain.save()
return redirect('success')
This is my HTML code for the form.
{% extends 'authmain.html' %}
{% block content %}
<h3> <p class="text-center"> Create a new Course Blockchain: </p> </h3>
<div class="card border-dark mb-3 mx-auto" align="center" style="width: 40rem;">
<div class="card-body">
<h5 class="card-title">
<form method='POST'>
{% csrf_token %}
<label for="year">Year: </label>
<input type="text" id="year" name="year" value=""><br>
<label for="code">Course Code: </label>
<input type="text" id="code" name="code" value=""><br>
<label for="name">Course Name: </label>
<input type="text" id="name" name="name" value=""><br>
<label for="slot">Slot: </label>
<input type="text" id="slot" name="slot" value=""><br>
<label for="sem">Semester: </label>
<input type="text" id="sem" name="sem" value=""><br>
<button class="btn btn-outline-primary" type="Submit"> Create </button>
</form>
</h5>
</div>
</div>
{% endblock %}
This is my urls.py.
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.home, name="home"),
path('register/', views.register, name="register"),
path('logout/', views.logoutuser, name="logoutuser"),
path('dashboard/', views.dashboard, name="dashboard"),
path('create_course/', views.create_course, name="create_course"),
path('success', views.success, name="success"),
]
This is the view function for success.
#login_required(login_url='/')
def success(request):
return render(request, 'success.html', {})
The issue is that you are not closing form tag in the authmain.html.
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<form action="{% url 'logoutuser' %}" method='POST'>
{% csrf_token %}
<button class="btn btn-outline-info mb-auto" type="submit">Logout</button>
----- CLOSING FORM TAG MISSING HERE ---
</li>
</ul>
and when you submit the form at Create Course, you actually trigger this form, which logs out the user. Add closing tag to the logout form and you'll fix your problem.
Sometimes debugging can be a bit tricky.
To save directly in the database in Django use Model.objects.create()
Chain.objects.create(user=request.user, name=name, year=year, sem=sem,
code=code, slot = slot)
You need to use a model form to achieve this
class MyForm(ModelForm):
class Meta:
model = MyModel
fields = []
And then you can do something like this:
form = MyForm(request.POST)
if form.is_valid():
new_item = form.save()
...
And it will save directly to the database.

Django 3.0 Forms: Form Errors are not showing onto template

###I have model named Publisher in models.py file.###
###And based on this model, a modelForm has made, called "RegistrationForm".###
###Which renders form on registration.html template.###
<br /> <br />**This is code of registration.html**
<pre><code>
```
<body>
<div class="container">
{% load my_filters %}
<div class="row">
<div class="col-md-6 offset-md-3">
{% if registered %}
<h1>Thank you for registering!</h1>
{% else %}
<h1>Register Here</h1>
<h3>Just fill out the form.</h3>
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ reg_form.non_field_errors }}
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.name.errors }}
<label for="{{ reg_form.name.id_for_label }}" >Name:</label>
{{ reg_form.name|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.email.errors }}
<label for="{{ reg_form.email.id_for_label }}">Email:</label>
{{ reg_form.email|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.contact.errors }}
<label for="{{ reg_form.contact.id_for_label }}">Contact:</label>
{{ reg_form.contact|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.password.errors }}
<label for="{{ reg_form.password.id_for_label }}">Password:
</label>
{{ reg_form.password|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.confirm_password.errors }}
<label for="{{ reg_form.confirm_password.id_for_label }}">Confirm
Password:</label>
{{ reg_form.confirm_password|addclass:'form-control' }}
</div>
</div>
<input type="submit" name="" value="Register">
</form>
{% endif %}
</div>
</div>
</div>
</body>
```
</code></pre>
### I am NOT using crispy forms just manually rendering Django forms and using manual template tag to add classes to fields.
**This is the template tag in used to add classes to form fields**
<code><pre>
```
#register.filter(name='addclass')
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})
```
</code></pre>
**This is the model in models.py**
<code><pre>
```
class Publisher(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField('Name', max_length=50)
email = models.EmailField('Email', unique=True)
password = models.CharField('Password', max_length=50)
contact = models.CharField('Contact #', max_length=16, unique=True, validators=[
RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format '+123456789'. Up to 15 digits allowed."
),
],)
def __str__(self):
return self.name
```
</code></pre>
**This is the form in forms.py file**
<code><pre>
```
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = Publisher
fields = ('name','email','contact','password')
def clean(self):
cleaned_data = super(RegistrationForm, self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError(
"password and confirm_password does not match"
)
```
</code></pre>
**This is the view in views.py file**
<code><pre>
```
def registration(request):
registered = False
if request.method == 'POST':
reg_form = RegistrationForm(data=request.POST)
if reg_form.is_valid():
user = reg_form.save()
user.save()
registered = True
else:
#Now issue is this printing statement working fine and printing errors on console.But
#errors are not showing on template.
print(reg_form.errors)
else:
reg_form = RegistrationForm()
return render(request, 'seller/registration.html',
{'reg_form': RegistrationForm,
'registered': registered
})
```
</code></pre>
I have seen all the stack overflow and tried many thing but none of them help me TO GET MY ERRORS ON FORM TEMPLATE (Though errors like password doesn't match and contact number error etc are getting printed on django console as defined in else statement of views.py file).
After filling form with wrong data pressing "submit" button it refreshes the form rather showing errors. And after filling form with with right data user gets registered (It shows "Thank you for registering" as defined in template). I know there must be silly thing I am doing or missing. Kindly let me know.

Contact Form is not working. IntegrityError at /contact/

Models.py
class ContactForm(models.Model):
name = models.CharField(max_length=50)
subject = models.CharField(max_length=200)
email = models.EmailField()
message = models.TextField()
def __str__(self):
return self.name
views.py
def contact(request):
if request.method == "POST":
name = request.POST.get('name')
subject = request.POST.get('subject')
email = request.POST.get('email')
message = request.POST.get('message')
ContactForm.objects.create(
name = name,
subject = subject,
email = email,
message = message
)
return render(
request,
'blog/contact.html',
{
'msg':'Details have been saved. We will get back to you.'
}
)
else:
return render(request, 'blog/contact.html')
contact.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="container wrap mb-5" style="margin-top: 100px">
<h2 class="text">Contact Us</h2>
<form action="{% url 'contact' %}" method="POST">
{% csrf_token %}
<input type="text" placeholder="Enter Your Name" name="name">
<input type="text" placeholder="Subject" name="subject">
<input type="email" placeholder="Enter Your Email" name="email">
<input type="message" placeholder="Write Your Message" name="msg">
<input type="submit" value="Send" name="Submit">
</form>
{% if msg %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endif %}
</div>
{% endblock %}
This error occured while I click on the submit button.
It shows IntegrityError at /contact/ NOT NULL constraint failed: blog_contacts.message.
I see that in the html, for the message input, the name tag is 'msg' and in view it is request.POST.get('message'). Hence it cannot find that post variable. Also there is no such input type as 'message', So you can change that too, The code for the line now looks like
<input type="text" placeholder="Write Your Message" name="message">
Also getting straight post objects is not recommended, it leaves you open to security holes. You should use Django forms to clean data before using user input. Check out the official documentation for more help
https://docs.djangoproject.com/en/3.0/topics/forms/

Django: How to use FilePathField to get file size

I work in a postproduction company, we have our media files on a server. Through the site running on a second server, the user would point to a file, perform some operations (calculating checksums for example) and save the results in the database.
I'm looking for a "best practices" example on how to use FilePathField to get the size of a file. I've read tutorials and searched in the docs, but I'm having trouble putting the pieces together for my needs.
Some relevant code (EDIT: corrected the views, #1 and #3 are printed):
models.py
class AssetTest(models.Model):
file_path = models.FilePathField(path=r"", default="")
file_name = models.CharField(max_length=250, default="")
file_size = models.IntegerField(default=0)
def __str__(self):
return self.file_path
forms.py
class AssetTestForm(forms.ModelForm):
class Meta:
model = AssetTest
fields = ("file_name", "file_size")
views.py
def asset_select(request):
if request.method == 'POST':
print("1")
form = AssetTestForm(request.POST)
if form.is_valid():
print("2")
form.save(commit=False)
form.file_name = request.FILES['file'].name
form.file_size = request.FILES['file'].size
form.save()
return HttpResponseRedirect('/assetmanage/assets/')
print("3")
else:
print("4")
form = AssetTestForm()
return render(request, 'assetmanage/asset_select.html', {'form': form})
asset_select.html
{% extends "assetmanage/base.html" %}
{% block title %}Add Asset{% endblock %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" name="asset_select" action="/assetmanage/asset/test/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label class="control-label col-sm-2">Select a file:</label>
<input type="file" name="asset_file">
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
In your FilePathField give the correct path name
FilePathField(path="/home/simon/",..)
cleaned_data of FilePathField will give you the exact path so using that to get the file name and file size of it...
form = AssetTestForm(request.POST)
if form.is_valid():
form.save(commit=False)
temp_file_obj = TemporaryFileUploadHandler(form.cleaned_data['file_path'])
form.instance.file_size = temp_file_obj.chunk_size
form.instance.file_name = form.cleaned_data['file_path'].split("/")[-1]
form.save()

Dropdown menu fed from auth_user

So I got to the end of my tether. I need to create a database that allows me to choose user names stored in auth_user table in the 'username' column. The model.py looks like this:
from django.db import models
from django.contrib.auth.models import User
class basehw(models.Model):
name = models.ForeignKey(User)
dept = models.CharField(verbose_name='dept', max_length=50, null=False)
location = models.CharField(verbose_name='location', max_length=50, null=False)
form:
from django.forms import ModelForm
from baza.models import basehw
class baseForm(ModelForm):
class Meta:
def __init__(self):
pass
model = basehw
add.html template(for now, it's a text field):
{% extends 'base/base.html' %}
{% load staticfiles %}
{% block content %}
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" charset="utf-8" language="javascript" src="{% static 'base/js/dataTables.bootstrap.js' %}"></script> </head>
<body>
<form action="{% url 'baza.views.add' %}" method="post">{% csrf_token %}
<div class="row">
<div class="col-md-4">
<label for="name">name:</label>
<input type="text" class="form-control" id="name" placeholder="name" name="name">
</div>
<div class="col-md-4">
<label for="site">site:</label>
<select class="form-control" id="site" name="site">
<option value="W16">W16</option>
<option value="W1602">W1602</option>
</select>
</div>
<div class="col-md-4">
<label for="hostname">hostname:</label>
<input type="text" class="form-control" id="hostname" name="hostname" placeholder="hostname">
</div>
<div class="col-md-4">
<label for="SN">serial number:</label>
<input type="text" class="form-control" id="SN" name="SN" placeholder="serial number">
</div>
</div>
<br />
<input class="btn btn-primary" type="submit" value="save"/>
<a href="{% url 'baza.views.Table' %}" class="btn btn-danger" type="button" >cancel</a>
<br /><br />
</form>
</body>
</html>
{% endblock %}
views.py:
def Table(request):
table = basehw.objects.all
return render_to_response('../templates/baza/baza.html',
{'table': table},
context_instance=RequestContext(request))
def add(request):
if request.method == 'POST':
form = baseForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/baza/')
else:
form = baseForm()
return render(request, 'baza/add.html', {
'form': form,
})
Using the following model, I am able to populate the 'name' field only by using the id of the whole record. Namely, when I enter '1', I get the user name that was saved as first in the auth_user table, when '2', the second one... Moreover, such model allows me to update the 'name' field only – no other field are possible to alter. The application uses an HTML template, and I'd like to turn the 'name' field to dropdown menu. So the problems are:
How should I create the model in order to make all fields editable?
What should I do to select a user's name instead of an ID from dropdown menu (dropdown menu fed from auth_user)? How should I describe in HTML?
Huge thanks in advance!
That's not how you write a template for a Django form. You need to use the form fields provided by the form object. For example:
<div class="col-md-4">
{{ form.name.label_tag }}
{{ form.name }}
{{ form.name.errors }}
</div>

Categories

Resources