Django - Creating Objects for models and saving it to MYSQL - python

I have designed an sample registration form and was using it save it to database . I can successfully save an entry to database but the problem is when create an second entry it overrides the first entry
register.html
<form action="/register_process/" method="post">
{% csrf_token %}
<label for="unamefield">Enter Username</label>
<input type="text" name="unamefield">
<label for="unamefield">Enter Password</label>
<input type="password" name="pwdfield">
<input type="submit" value="Register">
</form>
models.py
from django.db import models
class UserRegistration(models.Model):
USER_ID = models.CharField(primary_key=True, max_length=11)
USER_NAME = models.CharField(max_length=50)
PASSWORD = models.CharField(max_length=255, null=False)
class Meta:
db_table = 'USER'
views.py
def register_user(request):
args = {}
args.update(csrf(request))
return render_to_response('register.html', args)
def register_process(request):
if request.method == 'POST':
uname = request.POST.get('unamefield')
pwd = request.POST.get('pwdfield')
obj_userregistration = UserRegistration(USER_NAME=uname, PASSWORD=pwd)
obj_userregistration.save()
return HttpResponseRedirect('<html>Success</html>')

You've made a few errors in defining your model.
First, there is no reason to define your fields IN UPPER CASE. That's very strange.
More importantly, you have defined a USER_ID field as a charfield and set it to be the primary key. But you have not provided any way to actually generate a new value for this field. Unless you have a really good reason, you should not define a manual PK field at all, but let Django add an autoincremented integer field automatically.
But even more importantly than this, you should on no account do what you have done here at all. You are storing your passwords in clear text in the database, opening yourself to all sorts of hacking. Do not ever do this. Django includes a whole authentication framework where this is done properly, and there is absolutely no reason for you to bypass this as you have done. Do not do it.

Related

Django Validate Form As Per Database Entry ID

Hello Wonderful people,
I have made a form in Django which has some serial numbers stored in Django-admin database.
I am now creating another app and similar form, However I want is that the new Form should accept the serial number which is valid and checked as per the serial number got entered in the first form which is in app 1.
I am pasting a bit of my code for you to understand it more clearly with some screenshots.
<form method="POST" action="/reservation/home/">
{% csrf_token %}
<div class="form-group">
<label for="exampleFormControlInput1">Radio Serial Number</label>
<input type="text" class="form-control" id="exampleFormControlInput1" name= "sno"
placeholder="S/N123ABC123" required >
</div>
<button type="submit" class="btn btn-primary"> Submit </button>
</form>
views.py of new app.
def reserve(request):
if request.method == "POST":
sno = request.POST.get('sno')
date_req = request.POST.get('date_req')
reserve = Reserve( sno=sno, date_req=date_req )
reserve.save()
return render(request, 'home.html')
models.py of new app.
from django.db import models
# Create your models here.
class Reserve(models.Model):
sno = models.CharField(max_length=100)
date_req = models.DateField()
def __str__(self):
return self.sno
I want it to accept the serial number which got input by another form and validate it.
If the new serial number is not same as the database entry in previous form , It should display some error message that it is not found or not valid.
If it is valid it should accept that serial number and the entry should be done in new form.
I have provided the name and id as "sno"
I am not sure how to get any documentation or any video regarding this.
Any help would be highly appreciated.
In case you need more of information, please drop a comment or check my github repository : https://github.com/samatharkar/altiostar/tree/reserve-tool/inventory/reservation_app

How to save form data to my model in django

I am creating a newsletter application that requires the user's name and email. However each time I input form data . no change is reflected in the database
models.py
class NewUsers(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
date_added = models.DateField(auto_now_add= True)
class Meta:
verbose_name = "NewUser"
verbose_name_plural = "NewUsers"
def __str__(seld):
return self.email
views.py
def newsletter_subscribe(request):
if request.method == 'POST' :
form = NewUserForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name'] #variable to store cleaned data
email = form.cleaned_data['email']
instance = NewUsers(name= name, email = email)
instance.save()
if NewUsers.objects.filter(email = instance.email).exists():
print("Your email is already added to our database")
else:
instance.save()
print("Thank you for subscribing")
else:
form = NewUserForm()#display empty form
context = {'form':form}
template = "index.html"
return render(request ,template ,context )
Here is my template code
template
<form method="post" action="{%url 'subscribe'%}">
{% csrf_token %}
<label for="id_email_field">Name:</label> <input type="text"
name=""
required="" id="">
<label for="id_email_field">E-mail:</label> <input type="email"
name="email_field"
required="" id="id_email_field">
<button id="id_submit" name="submit" value="Subscribe"
type="submit">Subscribe
</button>
</form>
A few things I notice: First, a view must return an HttpResponse object. E.g., I recommend reading up here: https://docs.djangoproject.com/en/2.1/topics/http/views/ and here: https://docs.djangoproject.com/en/2.1/topics/forms/
So, since apparently you didnt get an error thrown at you pointing to this fact, I assume that the request.method never has been equal "POST". Maybe you could try to find out if this is the case? Therefore: could you also provide your template code, please.
Next, your code in the if form.is_valid() is quite contrived. The most natural thing to do here is just calling form.save(). This will create an instance in your db out of the cleaned form-data. In case, you need to do some adjustments, you can extend like this:
instance = form.save(commit=False)
# add some adjustments (instance.foo = bar)
instance.save()
Last, as noted before, you need to return an HttpResponse object which is usually done via
return redirect(url_name, ..)
Edit: since you now added the template code: Try to first let django render the fields for you: https://docs.djangoproject.com/en/2.1/topics/forms/#rendering-fields-manually
and then have a look at the source code of the template. Your name-input-field is missing a name tag and your email-input-field should have name="email" I think. You can django even let the whole form render for you (see docs again...) Without (correct) name tags in the input fields - it will not be possible to send or correctly assign the data inputted by the user.

Creating new account with or without ModelForms and designing with HTML/CSS

Is it best practice or necessary to create a new user using ModelForms in Django? What I have done is create a form in HTML and have that form POST to a function in one of my views to create an account. The reason I am asking this is because I am new to Django and upon playing with Django, I am not sure if ModelForms allow the flexibility of designing and decorating the generate HTML compared to if I create the form myself in HTML/CSS.
user model:
class BeeradUser(models.Model):
user = models.OneToOneField(User)
is_active = models.BooleanField(default=False)
activation_code = models.CharField(max_length=36)
registration function:
def register(request):
if request.method == "POST":
username = request.POST.get("username")
firstname = request.POST.get("firstname")
lastname = request.POST.get("lastname")
email = request.POST.get("email")
password = request.POST.get("password")
payload = {
"username": username,
"firstname": firstname,
"lastname": lastname,
"email": email,
"password": password
}
try:
unique_key = str(uuid.uuid4())
user = User(username=username, first_name=firstname, last_name=lastname, email=email, password=password)
# Modified User class
new_user = BeeradUser(user=user, activation_code=unique_key)
except TypeError as e:
return render(request, "error/404.html")
return render(request, "success.html", {"payload": payload})
else:
print "there"
poop = {"data": "sdfsdf"}
return render(request, "fail.html", {"payload": poop})
form:
<form class="signup-form" method="post" action="/auth/signup/" id="create-account">
{% csrf_token %}
<input id="signup-username" name="username" type="text" placeholder="Username">
<input id="signup-firstname" name="firstname" type="text" placeholder="First Name">
<input id="signup-lastname" name="lastname" type="text" placeholder="Last Name">
<input id="signup-email" name="email" type="email" placeholder="Email">
<input id="signup-password" name="password" placeholder="Password" type="password"><div id="pswd-msg"></div>
<input id="signup-confirm-password" name="confirm-password" placeholder="Confirm Password" type="password"><div id="result"></div>
<button type="submit" class="btn btn-xl" id="create-acc-btn" name="signup-submit">Create Account</button>
</form>
Obviously, the registration function does not save() the User to the database yet but I was wondering if this is the right approach versus using ModelForms
You didnt saved it.Try this to create new User
user = User(username=username, first_name=firstname, last_name=lastname, email=email, password=password)
user.save()
Also
new_user = BeeradUser(user=user, activation_code=unique_key)
new_user.save()
So, what happens when your user fails to enter all the required fields? Or enters something that isn't an email address in the email field? Your code will blithely create the user anyway, even though that instance would be invalid.
The main responsibility of forms is to validate data. That's especially important when it comes to something like creating users and adding passwords. The only difference your fields have over those automatically created by a Django form is the placeholder attribute, which you can easily set yourself in the form description.
I am not sure if ModelForms allow the flexibility of designing and decorating the generate HTML compared to if I create the form myself in HTML/CSS.
&
I was wondering if this is the right approach versus using ModelForms
Django offers a great tutorial which covers some of your question and there's also documentation, which holds all the answers you seek, but here's the TL;DR version:
Yes, Django offers all. And no, that is not the right approach.
Django ModelForm class objects' main goal is to connect the Model class objects to the HTML <form> and act as a median class, where you can test the fields with more than just database requirements. It offers functionalities like raising errors and making API calls for syncing things like captcha, which will happen in the back-end and not in the plain site of the user (html/css/javascript).
It does, as you've pointed out, allow auto generated fields and things of that nature, but those are more of a feature than they are it's purpose. And those can still be designed and decorated with your own HTML/CSS, but the back-end features I mentioned earlier will be unavailable..

Authenticating users that inherit from the django user class or django.contrib.auth.models.User

I sub-classed from the django User class to create my own personalized version of it. The User class I can talking about is django.contrib.auth.models.User.
This is what it looks like:
from django.db import models
from django.contrib.auth.models import User as Auth_User
class User(Auth_User):
# User data
Age = models.IntegerField(blank=False, default=0)
middle_name = models.CharField(blank=True, max_length=255)
# Properties
#property
def full_name(self):
return str(self.first_name + ' ' + (self.middle_name + ' ' if self.middle_name else '') + self.last_name)
# Overridden functions
def __unicode__(self):
return self.full_name
Please not that this is a simplified version of the model, there is more data, that really is not relevant to this question.
Now, when I try to authenticate via conventional means, its fails:
def login(request):
if request.method == 'GET':
return render(request, "User/login.html")
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
new_user = authenticate(username=username, password=password)
if new_user is not None:
if new_user.is_active:
login(request, new_user)
else:
print "User is not alive, he/she died! :("
return HttpResponseRedirect('/users/')
The HTML is nothing special:
{% extends 'layout.html' %}
{% block content %}
<form action="/users/login" method="post">
{% csrf_token %}
<label for="username">
Username:
<input type="text" name="username" id="username"/>
</label>
<label for="password">
Password:
<input type="password" name="password" id="password"/>
</label>
<input type="submit" value="Submit"/>
</form>
{% endblock %}
So, how do I authenticate a my User class that is subclassed from the django user class?
Make sure your model is in an app that's in your installed apps list, the Auth_USER_MODEL is set as #alecxe mentioned, and that you ran sync db.
If you ran sync db BEFORE you setup your new user model, you'll need to nuke the database and run it again now that your model is in place. This could explain why everything seems to be working but it's not.. From the docs:
Changing AUTH_USER_MODEL has a big effect on your database structure. It changes the tables that are available, and it will affect the construction of foreign keys and many-to-many relationships. If you intend to set AUTH_USER_MODEL, you should set it before creating any migrations or running manage.py migrate for the first time.
Changing this setting after you have tables created is not supported by makemigrations and will result in you having to manually write a set of migrations to fix your schema.

Django show ModelForm as html form

I am trying to do a very simple django webpage where a user fills 2 fields of a form with two numbers, submits them and gets a result at the third field. I am using ModelForms.
For the moment I am only interested in the first part, where the user navigates to the url and is prompted a page with the empty form. I do the following, but the page I see at my browser has no form, and only the submit button. I don't know if that's because the ModelForm I try to embed in the html code is still empty, but I tried to give it default values and it still didn't work.
Any help will be very appreciated! :)
urls.py:
urlpatterns = patterns('',
url(r'^calculator/', views.calculate)
)
models.py:
class Calc(models.Model):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
class CalcForm(ModelForm):
class Meta:
model = Calc
views.py:
def calculate(request):
c = CalcForm()
if request.method == 'POST':
#do the math
#return ...
else:
return render_to_response('home.html', {'calculator': c})
home.html:
<form action="/calculator/" method="post">
<table>
{{ calculator }}<!--I also tried .as_p, .as_ul...-->
</table>
<input type="submit" value="Submit" />
</form>
change the following:
class Calc(models.Model):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
to
class Calc(models.Model):
field1 = models.CharField(max_length=10)
field2 = models.CharField(max_length=10)
field3 = models.CharField(max_length=10)
Did you ever syncdb with the above code? Because if you would've, it must have thrown an error. This makes me think if your db has the correct tables or not. Make sure you syncdb after the above change.
Also, you should always check if an instance exist, This will also help you troubleshoot that if the object was correctly passed or not:
{% if calculator %}
<h3>Calculation Form</h3>
<form action="/calculator/" method="post">
<table>
{{ calculator }}
</table>
<input type="submit" value="Submit" />
</form>
{% endif %}
Your model should use models.CharField, not forms.CharField.

Categories

Resources