How to use Django sessions - python

I'm new to Django and i'm trying to build a Todo app with user authentication but i want to add sessions to it whereby everyone can have different tasks attached to their accounts but i don't know how to go about it. I've checked the Django documentation on it but i still don't get it.
Here's my models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class Task(models.Model):
name = models.CharField(max_length=15)
completed = models.BooleanField(default=False)
def __str__(self):
return self.name
class User(AbstractUser):
name = models.CharField(max_length=200, null=True)
email = models.EmailField(unique=True, null=True)
bio = models.TextField(null=True, blank=True)
USERNAME_FIELDS = "email"
REQUIRED_FIELDS = []
Then here's my view.py
from django.shortcuts import render, redirect
from .models import Task, User
from .forms import AddTaskForm
#login_required(login_url="loginPage")
def home(request):
tasks = Task.objects.all()
context = {"tasks": tasks, }
return render(request, "task/home.html", context)
# Add task view
# login_required(login_url="loginPage")
def addTask(request):
addTaskForm = AddTaskForm()
if request.method == "POST":
addTaskForm = AddTaskForm(request.POST)
if addTaskForm.is_valid():
addTaskForm.save()
return redirect('home')
context = {"addTaskForm": addTaskForm}
return render(request, "task/addtask.html", context)
# Update task view
#login_required(login_url="loginPage")
def update(request, pk):
updateTask = Task.objects.get(id=pk)
updateTaskForm = AddTaskForm(instance=updateTask)
if request.method == "POST":
updateTaskForm = AddTaskForm(request.POST, instance=updateTask)
if updateTaskForm.is_valid():
updateTaskForm.save()
return redirect('home')
context = {"updateTaskForm": updateTaskForm}
return render(request, "task/update-task.html", context)
# Delete task view
# login_required(login_url="loginPage")
def delete(request, pk):
deleteTask = Task.objects.get(id=pk)
if request.method == 'POST':
deleteTask.delete()
return redirect("home")
context = {"deleteTask": deleteTask}
return render(request, "task/delete-task.html", context)

Don't need to go with sessions. You need to improve model using Django ORM.
Like:
#models.py
class User(AbstractUser):
name = models.CharField(max_length=200, null=True)
email = models.EmailField(unique=True, null=True)
bio = models.TextField(null=True, blank=True)
USERNAME_FIELDS = "email"
REQUIRED_FIELDS = []
class Task(models.Model):
user = models.ForeignKey(User,on_delete=models.CASADE)
name = models.CharField(max_length=15)
completed = models.BooleanField(default=False)
def __str__(self):
return self.name
While saving tasks in Task model, provide the id of the user in the user field.

check this simple use of sessions in django :
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django import forms
from django.urls import reverse
class NewTaskForm(forms.Form) :
task = forms.CharField(label="Add Task ")
# Create your views here.
Tasks = []
def index(request) :
if "Tasks" not in request.session :
request.session["Tasks"] = []
return render(request , "tasks/index.html",{
"tasks" : request.session["Tasks"]
})
def add(request) :
if request.method == "POST" :
form = NewTaskForm(request.POST)
if form.is_valid() :
task = form.cleaned_data["task"]
request.session["Tasks"] += [task]
return HttpResponseRedirect(reverse("index"))
else :
return render(request , "tasks/add.html" , {
"form" : form
})
return render(request , "tasks/add.html" ,{
"form" : NewTaskForm()
})
with this method each user views their own task lists, i have a project same as what you looking for, here

Related

How do i pass data from a django function to another function

I have this signup django app and its more like a signup page for a website. I have an issue now, i made a one to one database relationship between the users data and their web profile
from django.db import models
import datetime
from django.utils import timezone
class UserDetail(models.Model):
SEX = (
('M', 'Male'),
('F', 'Female'),
)
first_name = models.CharField(max_length=60)
middle_name = models.CharField(max_length=60)
last_name = models.CharField(max_length=60)
gender = models.CharField(max_length=1, choices=SEX)
email = models.EmailField()
def __str__(self):
return '%s %s' % (self.first_name, self.last_name)
class WebDetail(models.Model):
user = models.OneToOneField(UserDetail, on_delete=models.CASCADE)
username = models.CharField(max_length=60)
password = models.CharField(max_length=60)
# TODO: i need to search how to do auto_now_add function
# time_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.username
and here is my views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import UserDetailForm, WebDetailForm
from .models import UserDetail, WebDetail
from django.shortcuts import redirect, reverse
def index(requests):
form = UserDetailForm()
if requests.method == "POST":
form = UserDetailForm(requests.POST)
if form.is_valid():
UserDetail.objects.create(**form.cleaned_data)
# print(requests.POST['first_name'])
# return HttpResponse('<h1>Hello</h1>')
# return redirect('signup:web_detail_create')
context = {'form': form}
return render(requests, 'signup/index.html', context)
def web_detail_create(requests):
form = WebDetailForm()
if requests.method == "POST":
form = UserDetailForm(requests.POST)
if form.is_valid():
# TODO: i need the function above to go with the users data and that would be refrenced as the user
# of the password and the username.
WebDetail.objects.create(**form.cleaned_data)
return redirect('signup:final')
context = {'form': form}
return render(requests, 'signup/final.html', context)
now i want to be able to pass in the users data to the web_detail_create view.
Thanks for your contribution

Trying to link two models with a ForeignKey but get the error "IntegrityError NOT NULL"

I have a model where a user posts a job vacancy, then other users can submit applications. The submit application model is called 'CandidatesSubmission' & pulls the 'title' from a different app/model 'JobPosts'.
I can add submit applications through the ADMIN page fine, but when trying to do so with a form I get "IntegrityError NOT NULL constraint failed: candidates_candidatessubmission.title_id."
I believe that I'm missing something in my Views.py that essentially says "use the title of job vacancy as the title field.
I have tried adding null=True, blank=False but which stops the error but the title isn't saved to the database.
Any suggestions on what I'm doing wrong would be great. Thank you
models.py
class CandidatesSubmission(models.Model):
title = models.ForeignKey('jobs.JobsPost', on_delete=models.CASCADE)
Fee = models.CharField(max_length=50, null=False, blank=False)
CandidateFirstName = models.CharField(max_length=50, null=True, blank=False)
CandidateSecondName = models.CharField(max_length=50, null=True, blank=False)
created = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.http import HttpResponseNotFound
from jobs.models import JobsPost
from candidates.models import CandidatesSubmission
from candidates.forms import CreateCandidatePostForm
from account.models import Account
from operator import attrgetter
# Create your views here.
def submit_candidates_view(request, slug):
context = {}
user = request.user
if not user.is_authenticated:
return redirect('must_authenticate')
form = CreateCandidatePostForm(request.POST or None, request.FILES or None)
if form.is_valid():
obj = form.save(commit=False)
author = Account.objects.filter(email=user.email).first()
obj.author = author
obj.save()
form = CreateCandidatePostForm()
context['form'] = form
accounts = CandidatesSubmission.objects.all()
context['accounts'] = accounts
return render(request, 'candidates/submit_candidates.html', context)
def response_view(request):
context = {}
accounts = CandidatesSubmission.objects.all()
context['accounts'] = accounts
return render(request, "candidates/response.html", context)
forms.py
from django import forms
from candidates.models import CandidatesSubmission
class CreateCandidatePostForm(forms.ModelForm):
class Meta:
model = CandidatesSubmission
fields = ['Fee', 'CandidateFirstName', 'CandidateSecondName']
def save(self, commit=True):
submission_post = self.instance
submission_post.Fee = self.cleaned_data['Fee']
submission_post.CandidateFirstName = self.cleaned_data['CandidateFirstName']
submission_post.CandidateSecondName = self.cleaned_data['CandidateSecondName']
if commit:
submission_post.save()
return submission_post
if you have "current" title, so your slug might store it, so you can use it like that.
def submit_candidates_view(request, slug):
context = {}
user = request.user
if not user.is_authenticated:
return redirect('must_authenticate')
form = CreateCandidatePostForm(post_slug=slug, request.POST or None, request.FILES or None)
if form.is_valid():
obj = form.save(commit=False)
author = Account.objects.filter(email=user.email).first()
obj.author = author
obj.save()
form = CreateCandidatePostForm()
context['form'] = form
accounts = CandidatesSubmission.objects.all()
context['accounts'] = accounts
return render(request, 'candidates/submit_candidates.html', context)
in your forms.py we replace __init__ method to receive slug of your title
class CreateCandidatePostForm(forms.ModelForm):
class Meta:
model = CandidatesSubmission
fields = ['Fee', 'CandidateFirstName', 'CandidateSecondName']
def __init__(self, *args, **kwargs):
self.post_slug = kwargs.pop("post_slug", None)
super().__init__(*args, **kwargs)
def save(self, commit=True):
submission_post = self.instance
submission_post.title = JobsPost.objects.get(slug=self.post_slug)
if commit:
submission_post.save()
return submission_post

django forms post request raising an error on __init__ method

I have a django form which takes a paramater from the view to initialize the MultipleChoiceField based on the user instance.
The form is working fine when loading the template.
when i submit the form the init method in the form raising an error.
My Model models.py
from django.db import models
from django.contrib.auth.models import User
class Group(models.Model):
group_name = models.CharField('Group name', max_length=50)
def __str__(self):
return self.group_name
class GroupMembers(models.Model):
group_name = models.ManyToManyField(Group)
members = models.ForeignKey(User, on_delete=models.CASCADE)
class Transactions(models.Model):
bill_type = models.CharField('Bill type',max_length=200)
added_by = models.ForeignKey(GroupMembers, on_delete=models.CASCADE)
added_to = models.ForeignKey(Group, on_delete=models.CASCADE)
purchase_date = models.DateField(auto_now=True)
share_with = models.CharField('Share among',max_length=250)
amount = models.IntegerField(default=0)
def __str__(self):
return self.bill_type
forms forms.py
from django import forms
from .models import Transactions, GroupMembers
class Bill_CreateForm(forms.ModelForm):
def __init__(self, user_list, *args, **kwargs):
super(Bill_CreateForm, self).__init__(*args, **kwargs)
self.fields['share_with'] = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,choices=tuple([(name, name.members) for name in user_list]))
class Meta:
model = Transactions
fields = (
'bill_type',
'amount',
'added_by',
'added_to',
'share_with',
)
** RESOLVED MY ISSUE WITH THE HELP OF #Alasdair "
EDITED SOLUTION
views views.py
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from .models import Transactions, Group, GroupMembers
from .forms import Bill_CreateForm
from django.http import HttpResponse, HttpResponseRedirect
def add_bills_home(request, id=None):
user = User.objects.get(pk=id)
grpname = Group.objects.filter(groupmembers__members=user)
gm = GroupMembers.objects.filter(group_name__group_name=grpname[0])
users_list = [i for i in gm]
if request.method == 'POST':
form = Bill_CreateForm(users_list, request.POST)
if form.is_valid():
print(form.cleaned_data['share_with'])
form.save()
form = Bill_CreateForm(users_list)
return render(request, 'bills/create_bill.html', {'form':form})
else:
form = Bill_CreateForm(users_list)
return render(request, 'bills/create_bill.html', {'form':form})
The error is
After submiting the form with data
the request.POST method returning
below data
i don't know if the request.POST method re-initializes the form with the filled data and pass it to the init method in the form.py.
Please help me with this

Django pass time value and user value to forms.py

I have a model like this:
from django.db import models
from django.contrib.auth.models import User
class Task(models.Model):
title = models.CharField(max_length=200)
pub_date = models.DateTimeField(default)
completed = models.BooleanField(default=False)
description = models.TextField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
def summary(self):
return self.description[:50]
def pub_date_pretty(self):
return self.pub_date.strftime('%b %e %Y')
def __str__(self):
return self.title
I have a forms.py like this because I don't want the user to be able to determine which user is saving the data and I want the pub_date to be the time now:
from django import forms
from .models import Task
from django.utils import timezone
class Taskform(forms.ModelForm):
class Meta:
model = Task
fields = ['title', 'description', 'completed']
My view is like this:
#login_required
def create(request):
form = Taskform(request.POST or None)
task = Task()
task.pub_date = timezone.datetime.now()
task.user = request.user
if form.is_valid():
form.save()
return redirect('')
return render(request, 'home/create.html', {'form': form})
I want to pass the time and the user to the form as it validates but I'm not sure how?
You can use form.save() with commit=True argument to take task instance and update it:
if form.is_valid():
task = form.save(commit=False)
task.pub_date = timezone.datetime.now()
task.user = request.user
task.save()
return redirect('')
Check detail here.

How can I set a default value to the model in Django?

I want to create a Invitation app which has a sender, receiver and message.
How can I set the current logged in user as a sender which is immutable?
In the model.py
class Invitation(models.Model):
from_user = models.CharField(max_length=100)
to_user = models.ForeignKey(User, related_name="invitations_received")
message = models.CharField(max_length=300)
timestap = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "{} to {}: {}".format(self.from_user, self.to_user, self.message)
In the views.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Game
from .models import Invitation
from .forms import InvitationForm
#login_required
def new_invitation(request):
if request.method == 'POST':
form = InvitationForm(data=request.POST, from_user=request.user)
if form.is_valid():
form.save()
return redirect('profiles_home')
else:
form = InvitationForm()
return render(request, "arosis/new_invitation.html", {'form': form})
In the forms.py
from django.forms import ModelForm
from .models import Invitation
from django.shortcuts import render
class InvitationForm(ModelForm):
class Meta:
model = Invitation
You cannot simply default to the current user because Django ORM is not normally aware of Django authentication system. You should either:
1) Pass the request.user while creating the model instance, like:
invitation = Invitation(from_user=request.user)
or
2) Use a middleware that adds the current user to the model each time it is saved. You can try one of these packages: https://www.djangopackages.com/grids/g/model-audit/
I solved it easily for myself as below:
In the models.py:
class Invitation(models.Model):
from_user = models.ForeignKey(User, related_name="invitations_sent")
to_user = models.ForeignKey(User, related_name="invitations_received",
verbose_name="User to invite",
help_text="Please Select the user you want.")
message = models.CharField("Optional Message", max_length=300, blank=True,
help_text="Adding Friendly Message")
timestap = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "{} to {}: {}".format(self.from_user, self.to_user, self.message)
In the views.py:
def new_invitation(request):
if request.method == 'POST':
invitation = Invitation(from_user=request.user)
form = InvitationForm(data=request.POST, instance=invitation)
if form.is_valid():
form.save()
return redirect('arosis_invite')
else:
form = InvitationForm(data=request.POST)
return render(request, "arosis/new_invitation.html", {'form': form})
In the forms.py:
class InvitationForm(ModelForm):
class Meta:
model = Invitation
exclude = ['from_user']
And in the template file:
I solved it really easy! by using:
{{ user.username }}

Categories