Display Data for Logged in User in model - python

Django version 2.2
I have models in django
class Class_teacher(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
empid = models.CharField(max_length=10)
standard = models.IntegerField()
division = models.CharField(max_length=1)
subject = models.CharField(max_length=200)
email = models.EmailField(max_length=30)
def __str__(self):
return self.first_name + ' -- ' + str(self.school)
class Student(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
classteacher = models.ForeignKey('Class_teacher', on_delete=models.CASCADE, )
reg_id = models.CharField(max_length=15)
parent_first_name = models.CharField(max_length=200)
parent_second_name = models.CharField(max_length=200)
email = models.EmailField(max_length=100)
def __str__(self):
return self.first_name + ' ' + self.last_name
views for adding student
class StudentCreate(LoginRequiredMixin, CreateView):
login_url = '/signin/'
model = Student
fields = ['first_name', 'last_name', 'parent_first_name','parent_second_name', 'email', 'reg_id']
success_url = '/dashboard/'
The webapp has login feature as below ,
def signin(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect('../dashboard/')
else:
return HttpResponse("Your account was inactive.")
else:
return HttpResponse("Invalid login details given")
else:
return render(request, 'webapp/login.html')
def dashboard(request):
email = request.user.email
if Class_teacher.objects.filter(email__iexact=email).count() == 1:
students = Student.objects.values('classteacher')
context = { 'students' : students}
return render(request, 'webapp/dashboard.html',context)
dashboard.html template
{% if students %}
<ol>
{% for student in students %}
<li>{{student.first_name}} {{student.last_name}}</li>
{% endfor %}
</ol>
{% else %}
<h3>No Students Added</h3>
{% endif %}
{% endblock %}
I used students = Student.objects.values('classteacher') but it doesnot provide with students names , just display an ordered list numbers .
I have two requirements
I have a modelform where the logged in teacher can add students , while I am adding students using the first mentioned view above it is triggering an error 'NOT NULL constraint failed: webapp.classteacher_id' , and when I change the add views to below it works well
class StudentCreate(LoginRequiredMixin, CreateView):
login_url = '/signin/'
model = Student
fields = ['first_name', 'last_name', 'parent_first_name','parent_second_name', 'email', 'reg_id' , 'classteacher']
success_url = '/dashboard/'
What i Want with the studentadd view is students should be added under the respective logged in teacher without providing the teacher's value via form
After login , the dashboard have to display students of the respective logged in teacher

You have filtered your students incorrectly.
Try this:
def dashboard(request):
email = request.user.email
class_teacher = Class_teacher.objects.get(email=email)
students = Student.objects.filter(classteacher=class_teacher)
return render(request, 'webapp/dashboard.html', {'students': students})

Related

How can I Display data of Model field last_bid(Foreign Key) to template

I am working on an Auction website using Django. I am trying to display data of the Last_bid field which is connected to Bid table with a foreign key. I tried many ways but nothing worked out.
The models.py file is:
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.base import Model
from django.db.models.deletion import CASCADE
from django.db.models.fields import CharField
from django.utils import timezone
class User(AbstractUser):
pass
class Category(models.Model):
category = models.CharField(max_length=64)
def __str__(self):
return f'{self.category}'
class AuctionListing(models.Model):
item_name = models.CharField(max_length=100)
item_image = models.ImageField(upload_to="products", null=True, blank=True)
detail = models.TextField()
price = models.IntegerField()
last_bid = models.ForeignKey('Bid', on_delete=models.CASCADE, blank=True, null=True, related_name='lst')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='publisher_listing', null=True, blank=True)
watchers = models.ManyToManyField(User, blank=True, related_name='watched_list')
pub_date = models.DateTimeField(auto_now=True, null=True)
deadline = models.DateTimeField(null=True)
list_category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='sortion')
closed = models.BooleanField(default=False)
def __str__(self):
return f'{self.item_name} - {self.price}'
class Bid(models.Model):
bid = models.IntegerField()
user = models.ForeignKey(User, on_delete=CASCADE)
auction = models.ForeignKey(AuctionListing, on_delete=CASCADE)
bid_date = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.bid}-{self.auction}'
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
com = models.TextField()
pub_date = models.DateField()
com_item = models.ForeignKey(AuctionListing, on_delete=models.CASCADE, related_name='get_comment')
def __str__(self):
return f'{self.user} - {self.pub_date}'
Views.py:
from django.contrib.auth import authenticate, login, logout
# from django.contrib.auth.decorators import login_required
from django.db import IntegrityError, reset_queries
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.urls import reverse
from django.forms import ModelForm
from .models import *
def index(request):
active_list = AuctionListing.objects.all().order_by('id').reverse()
return render(request, "auctions/index.html", {'active_list': active_list })
def login_view(request):
if request.method == "POST":
# Attempt to sign user in
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/login.html", {
"message": "Invalid username and/or password."
})
else:
return render(request, "auctions/login.html")
def logout_view(request):
logout(request)
return HttpResponseRedirect(reverse("index"))
def register(request):
if request.method == "POST":
username = request.POST["username"]
email = request.POST["email"]
# Ensure password matches confirmation
password = request.POST["password"]
confirmation = request.POST["confirmation"]
if password != confirmation:
return render(request, "auctions/register.html", {
"message": "Passwords must match."
})
# Attempt to create new user
try:
user = User.objects.create_user(username, email, password)
user.save()
except IntegrityError:
return render(request, "auctions/register.html", {
"message": "Username already taken."
})
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/register.html")
class CreateForm(ModelForm):
class Meta:
model = AuctionListing
fields = ['item_name', 'item_image', 'detail', 'price', 'deadline', 'list_category']
def create_listing(request):
user = request.user
if user.id is None:
return redirect('login')
if request.method == 'GET':
context = {
'form': CreateForm()
}
return render(request, 'auctions/create_listing.html', context)
else:
if request.method == 'POST':
form = CreateForm(request.POST or None, request.FILES or None)
if form.is_valid():
item_name = form.cleaned_data['item_name']
item_image = form.cleaned_data['item_image']
detail = form.cleaned_data['detail']
price = form.cleaned_data['price']
deadline = form.cleaned_data['deadline']
list_category = form.cleaned_data['list_category']
listing_created = AuctionListing.objects.create(
item_name = item_name,
item_image = item_image,
detail = detail,
price = price,
deadline = deadline,
list_category = list_category,
user = request.user,
)
listing_created.save()
return redirect('index')
def listing(request, pk):
user = request.user
list = AuctionListing.objects.get(id=pk)
if request.method == 'POST':
bid = request.POST.get('placebid')
user = request.user
form = Bid(bid=bid, user=user, auction=list)
form.save()
return render(request, 'auctions/listing.html', {'list': list})
The index.html is:
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Active Listings</h2>
{% for each in active_list %}
<div class="back">
<div class="imag">
<img src="{{ each.item_image.url }}" alt="">
</div>
<div class="detail">
<h1>{{ each.item_name }}</h1>
<h6>Published by: <span>{{ each.user }}</span></h6>
{% if each.last_bid %}
<p>Current Bid: <span>{{ each.last_bid.bid }} </span></p>
{% else %}
<p>Current Bid: <span>{{ each.price }} </span></p>
{% endif %}
<p>Published date: <span>{{ each.pub_date }}</span></p>
<p>DeadLine: <span>{{ each.deadline }}</span></p>
<div class="bid-detail">
<p>Initial Price: {{ each.price }}</p>
<p>Watchers: 10</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
I want to display the last_bid in index.html but I was not able to. Please help me with this problem. I will be thankful to you.

Drop down field shows values of all users

I have a form field in Django called Label. My problem is that the field shows the Labels of all users while I only want to show self created labels.
models
class Label(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
tag = models.CharField(max_length=25)
def __str__(self):
return self.tag
class Birthday(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=25, default="")
day = models.DateField()
label = models.ForeignKey(Label, on_delete=models.SET_NULL, default=0, null=True, blank=True)
def __str__(self):
return self.name
forms
class BirthdayForm(forms.ModelForm):
class Meta:
model = Birthday
fields = ('name', 'day', 'label')
class LabelForm(forms.ModelForm):
class Meta:
model = Label
fields = ('tag',)
template
<form method="POST">{% csrf_token %}
<table border="0">
{{ form }}
</table>
<button class="submitButton" type="submit">Submit</button>
</form>
This is the view for this template
view
#login_required
def index(request):
if request.method == "POST":
form = BirthdayForm(request.POST)
if form.is_valid():
birthday = form.save(commit=False)
birthday.user = request.user
birthday.save()
return redirect('index')
else:
#default_labels("Friend", request)
#default_labels("Family", request)
form = BirthdayForm()
birthday = Birthday.objects.filter(user=request.user)
username = request.user
return render(request, 'bd_calendar/index.html', {'form': form, 'birthday': birthday, 'username': username })

Properly configuring user registration using 2 forms

I am trying to submit 2 forms at a time to create my student user in Django. I have been struggling for a while now, but I think I'm finally closing to an end on how to manage 2 forms at a time for my users to register. But when I fill in the data and then click register, I get error: "This field is required." under my student ID field. What am I doing wrong ? Thanks.
class UserForm(forms.ModelForm):
password = forms.CharField(
label='Password',
max_length=32,
required=True,
widget=forms.PasswordInput,
)
password2 = forms.CharField(
label='Confirm',
max_length=32,
required=True,
widget=forms.PasswordInput,
help_text="Make sure they match!",
)
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'password', 'password2')
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('phone', 'student_ID', 'photo')
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_user_student(sender, instance, created, **kwargs):
if created:
Student.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_student(sender, instance, **kwargs):
instance.profile.save()
#csrf_protect
def student_register(request):
if request.method == 'POST':
form1 = UserForm(request.POST, prefix="user")
form2 = StudentForm(request.POST, prefix="profile")
if form1.is_valid() and form2.is_valid():
# create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
# create entry for UserProfile (extension of new_user object)
profile = form2.save(commit=False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("index")
else:
form1 = UserForm(prefix="user")
form2 = StudentForm(prefix="profile")
c = {
'form1': form1,
'form2': form2,
}
return render(request, "student_signup_form.html", c)
<form method="post">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>
First, you don't need #csrf_protect if you use {% csrf_token %} in template.
Second, you are probably getting student_ID required because you are trying to create a profile in signal providing just the user.
You can change your models like this:
models.py
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$', message='The ID needs to be 14 characters long.')], null=True, blank=True, default=None)
photo = models.ImageField(upload_to='students_images', null=True, blank=True, default=None)
phone = models.CharField(max_length=15, null=True, blank=True, default=None)
def __str__(self):
return self.user.username
views.py
def student_register(request):
data = dict()
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = StudentForm(request.POST, request.FILES)
if form1.is_valid() and form2.is_valid():
cd1 = form1.cleaned_data
username = cd1["username"]
password = cd1["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
cd2 = form2.cleaned_data
phone = cd2['phone']
student_ID = cd2['student_ID']
photo = cd2['photo']
Student.objects.create(user=new_user, phone=phone, student_ID=student_ID, photo=photo)
return redirect('index')
else:
form1 = UserForm()
form2 = StudentForm()
data['form1'] = form1
data['form2] = form2
return render(request, "student_signup_form.html", data)
template
<form action='' method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>
You can make StudentForm class a derived class of UserForm by declaring like class StudentForm(UserForm): and just submit one form that is StudentForm
It can be done like this also,
#models.py
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User)
student_ID = models.CharField(unique=True, max_length=14,validators=[RegexValidator(regex='^.{14}$',message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
User.student = property(lambda u: Student.objects.get_or_create(user=u)[0])
#forms.py
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('student_ID', 'photo', 'phone', )
#views.py
def student_register(request):
template_name = "student_signup_form.html"
context = {}
if request.method == 'POST':)
form = StudentForm(request.POST, instance=request.user.student)
if form.is_valid():
object = request.user.student
object.student_ID= form.cleaned_data['student_ID']
object.photo = form.cleaned_data['photo']
object.phone = form.cleaned_data['phone']
object.save()
return HttpResponseRedirect('index')
else:
form = StudentForm()
context['form'] = form
return render(request, template_name, context)

Django - Form not showing up on template only the button

I've been trying everything, but I can't figure out why it's not showing-up. I searched everywhere on this site with no luck. The button shows up but when I click than it give me a TypeError at get_profile, saying:
Exception Value:
get_profile() got an unexpected keyword argument 'username'
Here's my code:
models.py
class CustomUser(AbstractBaseUser):
email = models.EmailField('email address', unique=True, db_index=True)
username = models.CharField('username', max_length=50, unique=True, db_index=True)
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __unicode__(self):
return self.username
forms.py
from django import forms
from apps.accounts.models import CustomUser
class RegistrationForm(forms.ModelForm):
email = forms.EmailField(widget=forms.TextInput, label='email')
username = forms.CharField(widget=forms.TextInput, label='username')
password1 = forms.CharField(widget=forms.PasswordInput, label='Enter your password')
password2 = forms.CharField(widget=forms.PasswordInput, label='Re-type your password')
first_name = forms.CharField(widget=forms.TextInput, label='First Name')
last_name = forms.CharField(widget=forms.TextInput, label='Last Name')
class Meta:
model = CustomUser
fields = ['email', 'username', 'password1', 'password2', 'first_name', 'last_name']
def clean(self, password1, password2):
cleaned_data = super(RegistrationForm, self).clean()
if password1 in self.cleaned_data and password2 in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("Passwords don't match. Please enter both fields again")
return self.cleaned_data
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
views.py
def register(request):
"""
User Registration View
"""
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
CustomUser = form.save()
CustomUser.save()
return redirect('home.html')
else:
form = RegistrationForm()
return render_to_response('register.html', {
'form': form,
}, context_instance=RequestContext(request))
def get_profile(request):
username = CustomUser.username
return render_to_response(request, 'profile.html', {'username': username})
urls.py
urlpatterns = patterns ('',
url(r'register$', 'apps.accounts.views.register', name='register'),)
register.html
{% load staticfiles %}
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<body>
{% block body %}
<form method='POST' action="register" enctype= 'multipart/form-data'>{% csrf_token %}
<table>{{ form.ast_table}}</table>
<input type='submit' class="btn btn-default" value="Register" />
</form>
{% endblock %}
</body>
</html>
It seems that you don't have the right signature for the get_profile view function.
You should check your urls, you probably have something like
url(r'^profile/(?P<username>\w+/$', get_profile),
If so, your view should be
def get_profile(request, username):
#you can get the user
user = CustomUser.objects.get(username=username)
return render_to_response(request, 'profile.html', {'username': username, 'user': user})
CustomUser is the class. You need to fetch an instance before you can actually fetch its username.
Eg:
CustomUser.objects.get(pk=1).username
Gives you the username of the first user.
Also, its supposed to be {{form.as_table}} not ast_table

Django auto fill recipient in Django_messages

I'm building a job board and I'm using django_messages for private messages.
It works great but I want to auto fill the recipient form field with the username and I don't know why.
Some thoughts?
This is the view which I have candidates that applied for a job position. When I click send message, I need to auto fill the recipient field.
#views.py
class Screening(generic.DetailView):
model = Job
template_name = 'dashboard/screening.html'
def get_context_data(self, **kwargs):
context = super(Screening, self).get_context_data(**kwargs)
context['candidate_list'] = self.object.applied_to.all().order_by('candidate')
return context
#in the template
{% for candidate in candidate_list %}
{% candidate %}
Send message to this candidate
{% endfor %}
The models
#models.py
class Candidate(models.Model):
user = models.OneToOneField(User, primary_key=True)
birth = models.CharField(max_length=50)
...
class Job(models.Model):
candidate = models.ManyToManyField('Candidate', through='CandidateToJob')
title = models.CharField(max_length=500)
...
class CandidateToJob(models.Model):
job = models.ForeignKey(Job, related_name='applied_to')
candidate = models.ForeignKey(Candidate, related_name='from_user')
STATUS_CHOICES = (
('1', 'Not approved'),
('2', 'Approved'),
('3', 'Hired')
)
status = models.CharField(max_length=2, choices=STATUS_CHOICES)
class Meta:
unique_together = ("candidate", "job")
The django_messages app view to send messages
def compose(request, recipient=None, form_class=ComposeForm,
template_name='djangomessages/compose.html', success_url=None, recipient_filter=None):
if request.method == "POST":
sender = request.user
form = form_class(request.POST, recipient_filter=recipient_filter)
if form.is_valid():
form.save(sender=request.user)
messages.info(request, _(u"Message successfully sent."))
if success_url is None:
success_url = reverse('messages_inbox')
if 'next' in request.GET:
success_url = request.GET['next']
return HttpResponseRedirect(success_url)
else:
form = form_class()
if recipient is not None:
recipients = [u for u in User.objects.filter(**{'%s__in' % get_username_field(): [r.strip() for r in recipient.split('+')]})]
form.fields['recipient'].initial = recipients
return render_to_response(template_name, {
'form': form,
}, context_instance=RequestContext(request))
And the model in django_messages app
class Message(models.Model):
subject = models.CharField(_("Subject"), max_length=120)
body = models.TextField(_("Body"))
sender = models.ForeignKey(AUTH_USER_MODEL, related_name='sent_messages', verbose_name=_("Sender"))
recipient = models.ForeignKey(AUTH_USER_MODEL, related_name='received_messages', null=True, blank=True, verbose_name=_("Recipient"))

Categories