I am new to django, I created my custom user(auth_user) model. I need to create student registration form using custom user model according to my custom object
I have two models Title, User like this:
from django.db import models
#from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.contrib.auth.models import AbstractUser
class Title(models.Model):
value = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.value
class Meta:
db_table = 'title'
class User(AbstractUser):
title = models.ForeignKey(Title, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
db_table = 'user'
settings.py:
AUTH_USER_MODEL = 'student.User'
Here i have ForeignKey title field and User default fields first_name, last_name, email,password
My forms.py:
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.core import validators
from student.models import User
from student.models import Title
class StudentRegistrationForm(forms.Form):
filenumber = forms.CharField(label='Filenumber', max_length=45)
class StudentNewRegistrationForm(forms.ModelForm):
title = forms.CharField(required=True)
username = forms.CharField(required=True)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
email = forms.EmailField(required=True)
password1 = forms.CharField(required=True)
password2 = forms.CharField(required=True)
def __init__(self, *args, **kwargs):
super(StudentNewRegistrationForm, self).__init__(*args, **kwargs)
self.fields['title'] = forms.ModelChoiceField(queryset=Title.objects.all(), empty_label='Choose a title',required=False)
class Meta:
model = User
fields = ['title','username', 'first_name', 'last_name','email' 'password1', 'password2']
def save(self, commit=True):
user = super(StudentNewRegistrationForm, self).save(commit=False)
user.username = self.cleaned_data['username']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
user.title = self.cleaned_data['title']
user.password1 = user.set_password(self.cleaned_data['password1'])
user.password2 = user.set_password(self.cleaned_data['password2'])
if commit:
user.save()
return user
Here i have api response like below:
{"candidate":{"firstname":"Testuser","lastname":"test","salutation":10000,"email":"testing#gmail.com","username":"test"}}
This response coming form studentregistrationview:
from django.shortcuts import render, redirect
from django.urls import reverse
from student.forms import RegistrationForm
from django.contrib.auth import get_user_model
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from .forms import StudentRegistrationForm, StudentNewRegistrationForm
import requests
from django.http import JsonResponse
from django.http import HttpResponse
#from django.contrib.auth import get_user_model
from student.models import User
from student.models import Title
import json
import urllib
from django.conf import settings
from django.contrib import messages
def studentregistration(request):
form = StudentRegistrationForm()
if request.method == 'POST':
form = StudentRegistrationForm(request.POST)
if form.is_valid():
data = form.cleaned_data
inputdata = data.get('filenumber')
url = 'https://myapiurl/' + inputdata
result = requests.get(url)
finalresult = result.json()
studentapires = {'studentres': finalresult}
request.session['studentapires'] = studentapires
return redirect('/student/studentnewregistration')
else:
form = StudentRegistrationForm()
return render(request, 'student/studentregister.html', {'form': form})
I am creating new user object like below and i tried to persist object, here issue object is not persisting to user table
student_new_registration view i tried to create new User object like below
student_new_registration.py:
def student_new_registration(request):
studentapires = request.session.get('studentapires', None)
jsonresult = studentapires['studentres']['candidate']
user = User()
if jsonresult['salutation'] == 100000000:
salutation = 'Mister'
elif jsonresult['salutation'] == 100000002:
salutation = 'Madam'
title = Title.objects.get(value=salutation)
user.title = title
user.first_name = jsonresult['firstname']
user.last_name = jsonresult['lastname']
user.email = jsonresult['email']
user.username = jsonresult['username']
if request.method == 'POST':
form = StudentNewRegistrationForm(request.POST, instance=user)
if form.is_valid():
form.save()
return HttpResponse("Registration Completed")
return HttpResponse("Please Check Your Registration Form")
else:
form = StudentNewRegistrationForm(instance=user)
args = {'form': form}
return render(request, 'student/studentnewregistrationform.html', args)
Error:
full_clean() missing 1 required positional argument: 'self', form is not submitting (means form not going inside form.is_valid())
studentnewregistrationform.html:
{% extends 'base.html' %}
{% block head %}
<title>Student Profile Form</title>
{% endblock %}
{% block body %}
<div class="container">
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-sm-4">
<h3> Student Profile Form</h3>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.title.label }}</div>
<div class="col-sm-3">{{ form.title }}</div>
<div class="col-sm-4">{{ form.title.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.first_name.label }}</div>
<div class="col-sm-3">{{ form.first_name }}</div>
<div class="col-sm-4">{{ form.first_name.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.last_name.label }}</div>
<div class="col-sm-3">{{ form.last_name }}</div>
<div class="col-sm-4">{{ form.last_name.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.email.label }}</div>
<div class="col-sm-3">{{ form.email }}</div>
<div class="col-sm-4">{{ form.email.errors }}</div>
</div>
<br>
<br>
<div class="row">
<div class="col-sm-2">{{ form.username.label }}</div>
<div class="col-sm-3">{{ form.username }}</div>
<div class="col-sm-4">{{ form.username.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2"><label for="{{ form.password1.label }}">Password</label></div>
<div class="col-sm-3">{{ form.password1 }}</div>
<div class="col-sm-4">{{ form.password1.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2"><label for="{{ form.password2.id_for_label }}">ConfirmPassword</label></div>
<div class="col-sm-3">{{ form.password2 }}</div>
<div class="col-sm-4">{{ form.password2.errors }}</div>
</div>
<br><br>
<div class="row">
<div class="col-sm-2 col-sm-offset-2"> <input type="submit" name="submit" value="Submit" class="btn btn-primary"/></div>
<div class="col-sm-2"></div>
</div>
</form>
</div>
{% endblock %}
here issue is i am able to render all fields to registration form but i am not able to persist data and while persisting custom object i am getting this error
Manager isn't available; 'auth.User' has been swapped for 'student.User'
please help me any one, Thanks in advance...
You need to change User model inside your views.py file and in any other files where you are using User class. To new model. For this try to add following import:
from django.contrib.auth import get_user_model
User = get_user_model()
Instead of
from django.contrib.auth.models import User
Related
I am trying to display my stat update form in my Django template, however it isn't displaying. My stats below show up correctly, just not the form.
{{ stats.user }} | {{ stats.weight }} | {{ stats.date }}
Template:
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 text-center">
<h1>My Health</h1>
</div>
</div>
</div>
<div class="container-fluid">
<div class="col-auto text-center p-3 form-group">
<form method="post" style="margin-top: 1.3em;">
{{ update_form }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
</div>
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<p class="text-center"> {{ stats.user }} | {{ stats.weight }} | {{ stats.date }} </p>
</div>
</div>
</div>
{% endblock content %}
forms.py:
class StatUpdateForm(forms.Form):
class Meta:
model = Stats
fields = ('user', 'weight', 'date')
models.py:
class Stats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
weight = models.DecimalField(max_digits=5, decimal_places=2)
class Meta:
db_table = 'health_stats'
ordering = ['-date']
def __str__(self):
return f"You currently weigh {self.weight}, {self.user}"
views.py:
from django.shortcuts import render
from .models import Stats
from .forms import StatUpdateForm
from django.views import generic, View
from django.shortcuts import get_object_or_404
# from django.contrib.auth import authenticate
# from django.core.exceptions import ValidationError
# from .forms import RegistrationForm, LoginForm
def home(request):
return render(request, 'home.html')
class MyHealth(View):
def get(self, request, *args, **kwargs):
stats = Stats
context = {
'stats': stats,
"update_form": StatUpdateForm(),
'user': stats.user,
'weight': stats.weight,
'date': stats.date,
}
return render(request, 'MyHealth.html', context)
I've tried redefining the form in my views.py, but I'm unsure why it isn't pulling through, as the other parts of the context are.
Any help would be appreciated!
In the form, since you are using a model, you must extend from forms.ModelForm instead forms.Form, try to change that line in the forms.py
class StatUpdateForm(forms.ModelForm): # extends from forms.ModelForm
class Meta:
model = Stats
fields = ('user', 'weight', 'date')
I assume the form fields are rendering and the fields just aren't loaded with the correct values.
do this: StatUpdateForm(instance=stats) to make it an edit form
I'm trying to make a user active when I tap a button, and I'm using a DetailView.
views.py
from .models import Model
from django.contrib.auth.models import User
from django.shortcuts import redirect
class UserInspectView(DetailView):
model = Model
template_name = 'user-inspect.html'
# Make the user is_active = True
def accept (request, pk):
user = User.objects.get(id=pk)
user.is_active
return redirect('home')
...
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('inspect/<slug:slug>/', views.UserInspectView.as_view(), name='user-inspect'),
path('inspect/<int:pk>/accept/', views.accept, name="user-accept"),
...
]
user-inspect.html
{% extends 'base.html' %}
{% block title %} <title>User Inspection</title> {% endblock %}
{% block content %}
<div class="d-flex justify-content-center">
<div class="container d-flex flex-column">
<div class="ms-5 ps-5" >
<h3><strong>User:</strong> {{model.user}}</h3>
<br>
<h3><strong>Name:</strong> {{model.name}}</h3>
</div>
</div>
</div>
<br><br><br>
<div class="d-flex justify-content-center">
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group me-2 me-5 pe-5" role="group" aria-label="First group">
<form method="post" action="{% url 'user-accept' model.user.pk %}">
{% csrf_token %}
<button type="submit" class="btn btn-primary">Accept</button>
</form>
</div>
<div class="btn-group me-2 me-5 ps-5" role="group" aria-label="First group">
Back
</div>
</div>
</div>
{% endblock %}
models.py
from django.db import models
from django.contrib.auth.models import User
class Model(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
slug = models.SlugField(unique=True, blank=False, null=False)
Before my accept view looked like this
def accept (request, pk):
user = User.objects.get(id=pk)
user.is_active()
user.save()
return redirect('home')
but I changed it, because I got this error
TypeError at inspect/30/accept/
'bool' object is not callable
When I tap the Accept button, it takes me to the redirect that I have in the accept view, but the user is still inactive.
user.is_active is a boolean not a function.
def accept (request, pk):
user = User.objects.get(id=pk)
user.is_active = True
user.save()
return redirect('home')
i am using django-taggit to save tags. It save some tags but now its not working and idk why! still finding the solution. Please help me to find out what i am doing wrong. I am not getting any errors. But when i save the form using form.save_m2m() nothing is saved in my database. I have also checked my admin pannel. Nothing is storing in my db. Is there is any way to check this. I am also attaching the template.
views.py
from django.shortcuts import render,redirect,get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from . models import UserCreatedNote
from django.template.defaultfilters import slugify
from . forms import AddNoteForm
from taggit.models import Tag
# Create your views here.
#login_required
def notes(request):
if request.method=='POST':
form = AddNoteForm(request.POST)
if form.is_valid():
form_data = form.save(commit=False)
form_data.user = request.user
key = form_data.note_title
form_data.slug = unique_slug_generator(slugify(key))
form_data.save()
#to save tags
form.save_m2m()
notes = UserCreatedNote.objects.filter(user=request.user)
form = AddNoteForm()
context = {'notes': notes,'add_note_form':form}
return render(request,'usernotes.html',context)
notes = UserCreatedNote.objects.filter(user=request.user)
form = AddNoteForm()
context = {'notes': notes,'add_note_form':form}
return render(request,'usernotes.html',context)
#login_required
def edit(request,slug):
note = get_object_or_404(UserCreatedNote, slug=slug)
tagsList = []
for tag in note.note_tags.all():
tagsList.append(tag.name)
print(tagsList)
if request.method == 'POST':
form = AddNoteForm(request.POST, instance=note)
if form.is_valid():
form_data = form.save(commit=False)
form_data.user = request.user
key = form_data.note_title
form_data.slug = unique_slug_generator(slugify(key))
form_data.save()
#to save tags
form.save_m2m()
form = AddNoteForm(instance=note)
context={'note':note,'u_form':form}
return render(request,'edit_note.html',context)
form = AddNoteForm(instance=note)
context={'note':note,'u_form':form}
return render(request,'edit_note.html',context)
models.py
from django.db import models
from django.contrib.auth import get_user_model
from ckeditor.fields import RichTextField
from taggit.managers import TaggableManager
# Create your models here.
class UserCreatedNote(models.Model):
user = models.ForeignKey(get_user_model(),on_delete=models.CASCADE)
note_title = models.CharField(default='',max_length=100,blank=True,null=True)
note_tags = TaggableManager()
note_data = RichTextField(default='',max_length=5000,blank=True,null=True)
slug = models.SlugField(unique=True,max_length=100)
creation_time = models.DateTimeField(auto_now_add=True)
last_modified_time = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-creation_time',]
def __str__(self):
return str(self.user)
template
<form action="" method="post">
{% csrf_token %}
<div class="modal-body">
<div class="row">
{{ add_note_form.media }}
{% for field in add_note_form %}
<div class="form-group col-lg-12 col-md-12">
{{ field | as_crispy_field }}
</div>
{% endfor %}
<div class="form-group col-lg-12 col-md-12">
<label for="tags">Note Tags</label>
<input type="text" id="tags" data-role="tagsinput" class="form-control" name="note_tags">
</div>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<input type="submit" class="btn btn-success" value="Add">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</form>
My views-
from django.shortcuts import render, redirect
from .AuthForms import registerUserForm
from django.contrib import messages
from django.contrib.auth import login, authenticate
def registerUsers(request):
if request.method == 'POST':
ucf = registerUserForm(request.POST)
if ucf.is_valid():
ucf.save()
new_user = authenticate(username = ucf.cleaned_data['username'], password = ucf.cleaned_data['password1'])
login(request, new_user)
return redirect('content')
else:
ucf = registerUserForm()
return render(request, 'LoginAndSignUp/SignUpPage.html', {'ucf': ucf})
My form -
I have extended the usercreationform
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm , PasswordResetForm
from django import forms
class registerUserForm(UserCreationForm):
email = forms.EmailField(widget = forms.EmailInput(attrs={'placeholder':'Email', 'autocomplete':'off'}))
username = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Username','autocomplete':'off',}))
password1 = forms.CharField(widget= forms.PasswordInput(attrs={'placeholder':'Password'}))
password2 = None
class meta:
model = User
fields = ['username', 'email', 'password1']
class userLoginForm(AuthenticationForm):
username = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Username','autocomplete':'off'}))
password = forms.CharField(widget= forms.PasswordInput(attrs={'placeholder':'Password'}))
class userPasswordResetEmailForm(PasswordResetForm):
email = forms.EmailField(widget = forms.EmailInput(attrs={'placeholder':'Enter your email', 'autocomplete':'off',}))
class Meta:
model = User
fields = '__all__'
Here is my template. I suppose everything is correct but still its not saving the email
<form novalidate action="" method="post">
{%csrf_token%}
<div class="fieldWrapper">
{{ucf.email.errors}}
{{ucf.email}}
</div>
<div class="fieldWrapper">
{{ucf.username.errors}}
{{ucf.username}}
</div>
<div class="fieldWrapper">
{{ucf.password1.errors}}
{{ucf.password1}}
</div>
<div style="margin-bottom: 4%;">
<span class="director">Already with us? Log In</span>
<div class="director">
<i class="fa fa-compass"></i> Explore anonymously
</div>
</div>
<button class="primaryButton" type="submit">Sign Up</button>
</form>
The email field is not saving the email to database wherease the username and password is correctly being saved. Someone please help
Your code seems to be fine. I recreated your project and it works as intended. username, password and email are saved to the auth_user table. This is what mine looks like:
urls.py
urlpatterns = [
// other urls
path('users/', register_users, name='create_user')
]
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from users.forms import RegisterUserForm
def register_users(request):
if request.method == 'POST':
ucf = RegisterUserForm(request.POST)
if ucf.is_valid():
ucf.save()
new_user = authenticate(username=ucf.cleaned_data['username'], password=ucf.cleaned_data['password1'])
login(request, new_user)
return redirect('content')
else:
ucf = RegisterUserForm()
return render(request, 'users/sign_up_page.html', {'ucf': ucf})
forms.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django import forms
class RegisterUserForm(UserCreationForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={'placeholder': 'Email', 'autocomplete': 'off'}))
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username', 'autocomplete': 'off'}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
password2 = None
class Meta:
model = User
fields = ['username', 'email', 'password1']
sign_up_page.html
<form novalidate action="" method="post">
{% csrf_token %}
<div class="fieldWrapper">
{{ ucf.email.errors }}
{{ ucf.email }}
</div>
<div class="fieldWrapper">
{{ ucf.username.errors }}
{{ ucf.username }}
</div>
<div class="fieldWrapper">
{{ ucf.password1.errors }}
{{ ucf.password1 }}
</div>
<div style="margin-bottom: 4%;">
{# <span class="director">Already with us? Log In</span>#}
<div class="director">
{# <i class="fa fa-compass"></i> Explore anonymously#}
</div>
</div>
<button class="primaryButton" type="submit">Sign Up</button>
</form>
I am trying to create a student register page that allows the student to upload a profile photo. I am using Django User model and a StudentProfile model that has a OneToOne relation with User. Here are my codes:
student\models.py:
from django.db import models
from django.contrib.auth.models import User
class StudentProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,)
avatar = models.ImageField(upload_to='student_profile/', null=True, blank=True)
def __str__(self):
return self.user.username
students/form.py:
from django import forms
class ImageUploadForm(forms.Form):
profile_photo = forms.ImageField()
eLearning/views.py:
from django.contrib.auth import authenticate, login, get_user_model
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import LoginForm, RegisterForm
from students.forms import ImageUploadForm
from students.models import StudentProfile
User = get_user_model()
def register_page(request):
register_form = RegisterForm(request.POST or None)
photo_upload_form = ImageUploadForm(request.POST, request.FILES)
context = {
"register_form": register_form,
"photo_upload form": photo_upload_form
}
if register_form.is_valid():
# print(register_form.cleaned_data)
username = register_form.cleaned_data.get("username")
first_name = register_form.cleaned_data.get("first_name")
last_name = register_form.cleaned_data.get("last_name")
email = register_form.cleaned_data.get("email")
password = register_form.cleaned_data.get("password")
new_user = User.objects.create_user(
username, email, password,
first_name=first_name,
last_name=last_name,
)
if photo_upload_form.is_valid():
user = username
avatar = photo_upload_form.cleaned_data.get("profile_photo")
new_user_profile = StudentProfile.objects.create(user, avatar)
print(new_user)
return render(request, "auth/register.html", context)
auth/register.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row my-4">
<div class="col-5">
<form action="" method="post" class="form-control">
{% csrf_token %}
{{ register_form|crispy }}
<input type="submit" class="btn btn-default" value="Submit">
</form>
</div>
<div class="col-5">
<form method="post" enctype="multipart/form-data" class="form-control">
{% csrf_token %}
<input id="id_image" type="file" class="my-2" name="image">
{{ photo_upload_form|crispy }}
</form>
</div>
</div>
</div>
{% endblock %}
I am facing 2 problems:
1) The ImageUploadForm is not rendering on to register.html
2) A StudentProfile is not being created. User is being created fine.
I also tried replacing form with ModelForm for ImageUploadForm but I get a NULL constraint for student_user since Django doesn't what user for StudentProfile is.
I have been looking through Stack Overflow. All solutions are about how to upload a user image to Django admin but I haven't found anything that shows how to associate the uploaded image to User model during registration. Forgive me if this is a repeated question. Thanks.
In your eLearning/views.py:
the context you are passing to the html page the _ is missing
context = {
"register_form": register_form,
"photo_upload form": photo_upload_form
}
This will be the reason for the ImageUploadForm is not rendering on to register.html
It's should be like
context = {
"register_form": register_form,
"photo_upload_form": photo_upload_form
}
So I figured it out. The real issue was with the register.html code. The submit button only worked for the register_form so the photo upload form was not validating, hence student profile entry was not being created. Here's the updated code:
eLearning/views.py:
from students.forms import ImageUploadForm
from students.views import upload_pic
def register_page(request):
register_form = RegisterForm(request.POST or None)
photo_upload_form = ImageUploadForm(request.POST, request.FILES)
context = {
"register_form": register_form,
"photo_upload_form": photo_upload_form
}
if register_form.is_valid():
username = register_form.cleaned_data.get("username")
first_name = register_form.cleaned_data.get("first_name")
last_name = register_form.cleaned_data.get("last_name")
email = register_form.cleaned_data.get("email")
password = register_form.cleaned_data.get("password")
new_user = User.objects.create_user(
username, email, password,
first_name=first_name,
last_name=last_name,
)
upload_pic(request, photo_upload_form, username=username)
return render(request, "auth/register.html", context)
students/views.py:
from django.contrib.auth import get_user_model
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect, HttpResponse
from .models import StudentProfile
from .forms import ImageUploadForm
def upload_pic(request, form, username):
if request.method == 'POST':
if form.is_valid():
User = get_user_model()
user = User.objects.get(username=username)
avatar = form.cleaned_data.get('profile_photo')
new_user_profile = StudentProfile.objects.create(user=user, avatar=avatar)
new_user_profile.save()
register.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row my-4">
<div class="col-5">
<form action="" method="post" enctype="multipart/form-data" class="form-control">
{% csrf_token %}
{{ register_form|crispy }}
{{ photo_upload_form|crispy }}
<input type="submit" class="btn btn-default" value="Submit">
</form>
</div>
</div>
</div>
{% endblock %}
You have to make sure enctype="multipart/form-data" is inside your tags or the image upload form will not get validated. I would also recommend adding an image validation method to your form.py. Something Sachin pointed out earlier: image form and validation. Hope this helps.