I am trying to save the form data to database - django

I am trying to save user form data to database. I tried in these way but its not save anything i'm getting None value.
views.py
from django.shortcuts import render, redirect
from .forms import Signup
from .models import Signup
def Sign_up(request):
username = request.POST.get('username')
mobile_number = request.POST.get('mobile_number')
email = request.POST.get('email')
password = request.POST.get('password')
address = request.POST.get('address')
print("Hello form is submitted")
print(username)
print(mobile_number)
print(email)
print(password)
print(address)
post = Signup(username= username, mobile_number=mobile_number,email=email,
password=password, address=address)
post.save()
return render(request, 'sign_up/sign_up.html',{})
models.py
from django.db import models
class Signup(models.Model):
username = models.CharField(max_length=300, default='SOME STRING',
blank=True, null=True)
mobile_number = models.CharField(max_length=12, blank=True, null=True)
email = models.EmailField(max_length=50, blank=True, null=True)
password = models.CharField(max_length=50, blank=True, null=True)
address = models. CharField(max_length=100, blank=True, null=True)
print("Hi")
def __str__(self):
return self.username or ''
def __str__(self):
return self.mobile_number or ''
def __str__(self):
return self.email or ''
def __str__(self):
return self.password or ''
def __str__(self):
return self.address or ''
forms.py
from django import forms
from .models import Signup
class SignupForm(forms.Form):
username = forms.CharField(max_length=30, required=True)
mobile_number = forms.CharField(max_length=12)
email = forms.EmailField(max_length=50, required=True)
password = forms.CharField(max_length=50, required=True)
address = forms.CharField(max_length=100)
I'm getting like this
Django version 2.2, using settings 'project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Hello form is submitted
None
None
None
None
None
[01/May/2019 22:39:18] "GET /signup/? HTTP/1.1" 200 3360

You are creating a Signup object in a wrong manner, create it like this:
you can create model form instead like this:
class SignupForm(forms.ModelForm):
class Meta:
model = Signup
fields = ('username', )#pass fields here
and in your view you get the values entered by user like this:
formToSave = SignupForm(request.POST,request.FILES)
if formToSave.is_valid():
product = formToSave.save()
but if you don't want to use the model form you can create the object Signup and then save it as you are doing but make sure before creating the object you are getting all the form values in your views by printing them(as you are already doing)
post = Signup.objects.create(username= username, mobile_number=mobile_number,email=email,
password=password, address=address)
then save it
post.save()

If you are using this model in production be careful.
Storing non hashed password is a really bad practice.
I think you are trying to reinvent the wheel here.
There is several ways to manage the User model in django.
If you decide to create your own User system, please read this first:
https://docs.djangoproject.com/en/2.2/topics/auth/customizing/
Extending the existing User model
There are two ways to extend the default User model without substituting your own model. If the changes you need are purely behavioral, and don’t require any change to what is stored in the database, you can create a proxy model based on User. This allows for any of the features offered by proxy models including default ordering, custom managers, or custom model methods.
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user. For example you might create an Employee model:
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
Using a custom user model when starting a project
If you’re starting a new project, it’s highly recommended to set up a custom user model, even if the default User model is sufficient for you. This model behaves identically to the default user model, but you’ll be able to customize it in the future if the need arises:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migrations or running manage.py migrate for the first time.
Also, register the model in the app’s admin.py
Further in the Doc
Specifying a custom user model
When you start your project with a custom user model, stop to consider
if this is the right choice for your project.
Keeping all user related information in one model removes the need for
additional or more complex database queries to retrieve related
models. On the other hand, it may be more suitable to store
app-specific user information in a model that has a relation with your
custom user model. That allows each app to specify its own user data
requirements without potentially conflicting or breaking assumptions
by other apps. It also means that you would keep your user model as
simple as possible, focused on authentication, and following the
minimum requirements Django expects custom user models to meet.
If you use the default authentication backend, then your model must
have a single unique field that can be used for identification
purposes. This can be a username, an email address, or any other
unique attribute. A non-unique username field is allowed if you use a
custom authentication backend that can support it.
The easiest way to construct a compliant custom user model is to
inherit from AbstractBaseUser. AbstractBaseUser provides the core
implementation of a user model, including hashed passwords and
tokenized password resets. You must then provide some key
implementation details
As a reference here is the doc page about user authentication: https://docs.djangoproject.com/en/2.2/topics/auth/
If you want to choose the default django User system: https://docs.djangoproject.com/en/2.2/topics/auth/default/ and more info about the default user api : https://docs.djangoproject.com/en/2.2/ref/contrib/auth/

Related

How can I link model in new app with specific model data in allauth?

In Django, I have installed allauth. Then I have created a new app, where user's actions will be. I want to link each of the actions with allauth's user data within EmailAddress model.
My questions are:
Normally, data is defined by user_action = models.CharField(max_length=200) and such. ForeignKey on user action does not allow defining field types, at least from what I've seen. How can I define it, or is it okay not to define it?
How can I define the relationship with data in allauth's model that's not anywhere near this new app? For example, I have:
from django.db import models
import allauth.account.models
class Button(models.Model):
button_one = models.ForeignKey('EmailAddress', on_delete=models.CASCADE)
def __str__(self):
return self.button_one
It does not work. The error shows:
input.Button.comment: (fields.E300) Field defines a relation with model 'EmailAddress', which is either not installed, or is abstract.
input.Button.comment: (fields.E307) The field input.Button.comment was declared with a lazy reference to 'input.emailaddress', but app 'input' doesn't provide model 'emailaddress'.
The allauth model data ("user") in question is:
class EmailAddress(models.Model):
user = models.ForeignKey(allauth_app_settings.USER_MODEL,
verbose_name=_('user'),
on_delete=models.CASCADE)
email = models.EmailField(unique=app_settings.UNIQUE_EMAIL,
max_length=app_settings.EMAIL_MAX_LENGTH,
verbose_name=_('e-mail address'))
verified = models.BooleanField(verbose_name=_('verified'), default=False)
primary = models.BooleanField(verbose_name=_('primary'), default=False)
objects = EmailAddressManager()
I'm using virtualenv and have allauth installed within the project.
So EmailAddress is your User model?
In that case you might be able to do this via the standard way by referring to settings.py
Import . from settings
class Button(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)

Django: how to write code for modelform of user registration

I would want to make register form and check if the
user's email is a new one by checking the DB.
But the problem is that I don't know how to make it.
I tried using unique=True to Field and clean_email() method.
I have 2 questions.
1) When ValidationError happens at the step of unique=True,
how could I catch that error? should I override the clean_field() method
of Model? And How could I make it?
2) how could I write efficient and nice code for this registration app?
Below are the source code i made.
# models.py
from django.db import models
class User(models.Model):
university = models.ForeignKey('University')
mail = models.EmailField(unique=True)
password = models.CharField()
nickname = models.CharField()
class University(models.Model):
name = models.CharField()
mail = models.CharField()
from django.forms import ModelForm
class LoginForm(ModelForm):
class Meta:
model = User
fields = ('mail', 'password')
class RegisterForm(ModelForm):
class Meta:
model = User
def clean_mail():
data = self.cleaned_data['mail']
if User.objects.filter(mail=data).exists():
raise forms.ValidationError("This email is already exists")
# views.py
def register(request):
if request.method == 'POST':
###
if form.is_valid():
I am so confused to make this.
I am waiting for a help Thanks in advance ;)
You don't catch that error. Django does it for you: when you call form.is_valid(), it calls each of the clean_field methods and catches any ValidationError exceptions, putting them into the form.errors attribute.
So, what you have is already fine.
Except for the major, huge, absolutely vital issue that you should never store passwords in plain text. Don't create your own standalone user class: inherit from AbstractBaseUser and use Django's built-in methods to create users and hash their passwords. You must not do it like this.
First of All, Your clean_mail() should return self.cleaned_data['mail'] , if error is not raised. Although clean_mail is not required here
Secondly, Django will automatically check for uniqueness of the Email if you set unique=Ture in Model. An error would be raised if it is not unique.
You can over-ride unique error text by providing that in ModelForm's Meta options.
e.g.
class RegisterForm(ModelForm):
class Meta:
model = User
error_messages = {
'mail': {
'unique': _("This email already exists"),
},
}
Note: error_messages option has been added in django v1.6 only...
For previous versions:
You can over-ride the field mail in the ModelForm directly. e.g Define at top of the ModelForm
class RegisterForm(ModelForm):
mail = forms.EmailField(max_length=255, error_messages = { 'unique': 'xyz....',})
class Meta:.......
you can find reference here:https://docs.djangoproject.com/en/1.5/ref/forms/fields/#error-messages
Take a quick look at the following page: https://docs.djangoproject.com/en/dev/ref/models/instances/
The section "Validating objects" guides you through the steps in model validation.
If you require single-column uniqueness on User.mail, simply add the keyword unique=True to the Charfield. The stock implementation of validate_unique() will handle this.

A Django form for entering a 0 to n email addresses

I have a Django application with some fairly common models in it: UserProfile and Organization. A UserProfile or an Organization can both have 0 to n emails, so I have an Email model that has a GenericForeignKey. UserProfile and Organization Models both have a GenericRelation called emails that points back to the Email model (summary code provided below).
The question: what is the best way to provide an Organization form that allows a user to enter organization details including 0 to n email addresses?
My Organization create view is a Django class-based view. I'm leaning towards creating a dynamic form and an enabling it with Javascript to allow the user to add as many email addresses as necessary. I will render the form with django-crispy-forms and django-floppyforms for display on a site using Twitter Bootstrap.
I've thought about doing this with a BaseGenericInlineFormset embedded within the form, but this seems like overkill for email addresses. Embedding a formset in a form delivered by a class-based view is cumbersome too.
Note that the same issue occurs with the Organization fields phone_numbers and locations.
Code
emails.py:
from django.db import models
from parent_mixins import Parent_Mixin
class Email(Parent_Mixin,models.Model):
email_type = models.CharField(blank=True,max_length=100,null=True,default=None,verbose_name='Email Type')
email = models.EmailField()
class Meta:
app_label = 'core'
organizations.py:
from emails import Email
from locations import Location
from phone_numbers import Phone_Number
from django.contrib.contenttypes import generic
from django.db import models
class Organization(models.Model):
active = models.BooleanField()
duns_number = models.CharField(blank=True,default=None,null=True,max_length=9) # need to validate this
emails = generic.GenericRelation(Email,content_type_field='parent_type',object_id_field='parent_id')
legal_name = models.CharField(blank=True,default=None,null=True,max_length=200)
locations = generic.GenericRelation(Location,content_type_field='parent_type',object_id_field='parent_id')
name = models.CharField(blank=True,default=None,null=True,max_length=200)
organization_group = models.CharField(blank=True,default=None,null=True,max_length=200)
organization_type = models.CharField(blank=True,default=None,null=True,max_length=200)
phone_numbers = generic.GenericRelation(Phone_Number,content_type_field='parent_type',object_id_field='parent_id')
taxpayer_id_number = models.CharField(blank=True,default=None,null=True,max_length=9) # need to validate this
class Meta:
app_label = 'core'
parent_mixins.py
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.db import models
class Parent_Mixin(models.Model):
parent_type = models.ForeignKey(ContentType,blank=True,null=True)
parent_id = models.PositiveIntegerField(blank=True,null=True)
parent = generic.GenericForeignKey('parent_type', 'parent_id')
class Meta:
abstract = True
app_label = 'core'
you can try using .split(), with this your form would look easier and users wont have to keep on adding text fields.
What you can do is, make one textbox where user can add multiple emails and separate them by a coma. and then in your views you can do this
email = emails.split(',')
for i in emails:
#assign email and save.
in case of having an email type
it might still be a good idea to build a system like that. what you can do is
abc#gmail.com-work,xyz#k.com-school
and then you can split them like this
email-type=email.split(',')
for i in email-type:
email=i.split('-')[0]
if i.split('-')[1]:
type=i.split('-')[1]
else:
#give it a default type

Django user profile

When adding additional fields to a user profile, such as location, gender, employer, etc., should I be adding additional columns to django.contrib.auth.models.User and saving it there? Or should I be creating a new table to save user profile information?
Also, when a user uploads a profile picture, should I be saving this in the same table? (Note this is not a production server, I'm just doing this on my local runserver to figure things out). Thank you
You have to make a model for the user profile:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
location = models.CharField(max_length=140)
gender = models.CharField(max_length=140)
employer = models.ForeignKey(Employer)
profile_picture = models.ImageField(upload_to='thumbpath', blank=True)
def __unicode__(self):
return u'Profile of user: %s' % self.user.username
Then configure in settings.py:
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
Conceptually, OneToOneField is similar to a ForeignKey with unique=True, but the “reverse” side of the relation will directly return a single object. This is the recommended way of extending User class.
class UserProfile(models.Model):
user = models.OneToOneField(User)
...
Current Django is 1.9 and here are some updates to the outdated accepted answer
use models.OneToOneField(User)
add related_name='profile'
use .__str__() and .format() for Python 3
like so
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
location = models.CharField(max_length=140)
gender = models.CharField(max_length=140)
...
def __str__(self):
return 'Profile of user: {}'.format(self.user.username)
Using related_name you can access a user's profile easily, for example for request.user
request.user.profile.location
request.user.profile.gender
No need for additional lookups.
Django provides a way of storing additional information about users in a separate table (called user profile).
Starting with Django 1.5 you can replace the default User with your custom user object using a simple settings entry:
AUTH_USER_MODEL = 'myapp.MyUser'
For slightly more details, check this Django documentation entry.
There's a solution I found here. Basically you just extend the default form UserCreationForm but keeping the same name. It works seamlessly with the way Django's docs tell you to do UserProfiles.
Answer can be updated to add signal receiver which will create the profile if it does not exist and update if it is already there.
#receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
This https://simpleisbetterthancomplex.com/tutorial/2016/11/23/how-to-add-user-profile-to-django-admin.html post also includes how to edit, list the custom profile in admin panel.
The current 2 top answers are outdated
If you reference User directly (for example, by referring to it in a foreign key), your code will not work in projects where the AUTH_USER_MODEL setting has been changed to a different user model. [..] Instead of referring to User directly [..] when you define a foreign key or many-to-many relations to the user model, you should specify the custom model using the AUTH_USER_MODEL setting.
from django.conf import settings
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="userprofile",
)
https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#referencing-the-user-model
If you want to get user profile data from user objects.
from django.contrib.auth.models import User
request.user.profile

Registration form with profile's field

I have a simple question. This is my profile:
class Profile(models.Model):
user = models.ForeignKey(User, unique=True)
born = models.DateTimeField('born to')
photo = models.ImageField(upload_to='profile_photo')
I want to create a registration form with these fields (from User and Profile models):
username
first_name
last_name
born
photo
These fields are required.
How do I do that?
How does get_profile() work in a template for this issue?
Thank you :)
Setup
Are you using the django-profiles and django-registration projects? If not, you should—much of this code has already been written for you.
Profile
Your user profile code is:
class Profile(models.Model):
user = models.ForeignKey(User, unique=True)
born = models.DateTimeField('born to')
photo = models.ImageField(upload_to='profile_photo')
Have you correctly setup this profile in your Django settings? You should add this if not, substituting yourapp for your app's name:
AUTH_PROFILE_MODULE = "yourapp.Profile"
Registration Form
django-registration comes with some default registration forms but you specified you wanted to create your own. Each Django form field defaults to required so you should not need to change that. The important part is just making sure to handle the existing registration form fields and adding in the profile creation. Something like this should work:
from django import forms
from registration.forms import RegistrationForm
from yourapp.models import Profile
from registration.models import RegistrationProfile
class YourRegistrationForm(RegistrationForm):
born = forms.DateTimeField()
photo = forms.ImageField()
def save(self, profile_callback=None):
new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],
password=self.cleaned_data['password1'],
email = self.cleaned_data['email'])
new_profile = Profile(user=new_user, born=self.cleaned_data['born'], photo=self.cleaned_data['photo'])
new_profile.save()
return new_user
Bringing it together
You can use the default django-registration templates and views, but will want to pass them your form in urls.py:
from registration.backends.default import DefaultBackend
from registration.views import activate
from registration.views import register
# ... the rest of your urls until you find somewhere you want to add ...
url(r'^register/$', register,
{'form_class' : YourRegistrationForm, 'backend': DefaultBackend},
name='registration_register'),