How save specific user instance into database using django views - python

I created models called Interview, Users, Interview_interviewer like wise...
Interview_interviewer table has foreign keys from other models.
I just want to save data from both 2 tables to Interview_interviewer(Without django forms) table which is many to many table. So I just created the views and template for it. When button clicks it save the Interviewers to table along side with the interview. But when do it, It gave me and error called "User matching query does not exist".
/home/govinda/DMG/test3/myapp/views.py in hod_inter_interviewer_2
usr = User.objects.get(id=pid)
What should I do?
class Interview(models.Model):
Time = models.TimeField()
Date = models.DateField()
Venue = models.ForeignKey('Venue')
HOD = models.ForeignKey(User)
Vacancy = models.ForeignKey('Vacancy', on_delete=models.CASCADE)
Department = models.ForeignKey(Department, on_delete=models.CASCADE)
InterviewType = models.ForeignKey(InterviewType, on_delete=models.CASCADE)
Interviewer_Review = models.TextField(blank=True, null=True)
HOD_Review = models.TextField(blank=True, null=True)
HR_Review = models.TextField(blank=True, null=True)
NoOfPasses = models.PositiveIntegerField(blank=True, null=True)
NoOfFails = models.PositiveIntegerField(blank=True, null=True)
NoOfOnHolds = models.PositiveIntegerField(blank=True, null=True)
InterviewNo = models.IntegerField(blank=True, null=True)
Post = models.ForeignKey(Post, on_delete=models.CASCADE)
and
class Users(models.Model):
User = models.OneToOneField(User)
FullName = models.CharField(max_length=100)
Post = models.ForeignKey(Post)
UPhoto = models.FileField(upload_to=User_directory_path,null = True,blank=True)
Department = models.ForeignKey(Department)
UserRole = models.ForeignKey(UserRole)
def __str__(self):
return u'{}'.format(self.User)
and
class Interview_Interviewer(models.Model):
Interview = models.ForeignKey(Interview)
Interviewer = models.ForeignKey(User)
def __str__(self):
return u'{}'.format(self.Interviewer)
views are...
def hod_pre_interviwer_list(request, iid):
inter = Interview.objects.get(id=iid)
a = UserRole.objects.get(Role="Interviewer")
viewer = Users.objects.filter(UserRole=a.id)
return render(request, 'hod_inter_create_2.html', {'viewer': viewer, 'inter': inter, 'a':a})
def hod_inter_interviewer_2(request, iid, pid):
inter = Interview.objects.get(id=iid)
usr = User.objects.get(id=pid)
a = UserRole.objects.get(Role="Interviewer")
viewer = Users.objects.filter(UserRole=a.id)
usr_id = Users.objects.get(User=a.id)
inter_id = inter
person_id = usr_id
form = Interview_Interviewer(Interview=inter_id, Interviewer=person_id)
form.save()
return render(request, 'hod_inter_create_2.html', {'viewer': viewer, 'inter': inter})
urls are...
urlpatterns = [
url(r'^hod/hod_vacancy/test/part2/inter_list/(\d+)/$', hod_pre_interviwer_list, name="inter1"),
url(r'^hod/hod_vacancy/test/part2/inter_list/(\d+)/(\d+)/$', hod_inter_interviewer_2, name="inter2"),
]
template is...
<a type="submit" class="btn btn-primary" href="/hod/hod_vacancy/test/part2/inter_list/{{ inter.id }}/{{ viewer.id }}">Add</a>

Try using named groups in your url patterns
urlurl(r'^hod/hod_vacancy/test/part2/inter_list/?P<iid>[0-9]+)/?P<pid>[0-9]+/$', hod_inter_interviewer_2, name="inter2"),
If that doesn't work then i suggest trying User.object.get(pk=pid) as in most doc examples.
And make sure that there is a user with that id (iid) in the url.
You should also use get_object_or_404 for getting any single object from a model in the view as it gives a more user friendly and appropriate error.

Related

How to use Authentication in DRF

I am trying to convert my current project(It is developed in Django) to DRF. So, I set up DRF in my project then I wrote an endpoint for after user login on the session I need to get the response when I test the my-reviews API.
models.py
class customer(models.Model):
cust_id = models.IntegerField(null="true")
email = models.CharField(max_length=100)
# reemail = models.CharField(max_length=100, null='true')
password = models.CharField(max_length=500)
repassword = models.CharField(max_length=500, null='true')
firstname = models.CharField(max_length=225)
lastname = models.CharField(max_length=225, null=True)
state = models.CharField(max_length=64, null=True)
city = models.CharField(max_length=64, null=True)
location = models.CharField(max_length=225, null=True)
Zip = models.CharField(max_length=64)
mailing = models.CharField(max_length=1000)
added_date = models.DateTimeField(editable=False)
modified_date = models.DateTimeField(null=True, blank=True)
last_loggedin = models.DateField()
views.py
#api_view(['GET'])
def myservicereviewAPI(request):
# If a user session is logged out it will redirect to the home page.
if ((request.session.get('email') is None) or (request.session.get('email') == "")):
# redirecting the user after logging out to the home page.
return HttpResponseRedirect("/home")
if request.method == 'GET':
students = services_review.objects.all().order_by('-added_date')
serializer = ServicesReviewSerializer(students, many=True)
return Response(serializer.data)
urls.py
path('myservicereviewAPI', views.myservicereviewAPI, name='myservicereviewAPI'),
Results of Postman when I run 'myservicereviewAPI'
After login Browser results of 'myservicereviewAPI'
Please Help me to achieve this.

Django M2M field in a Model Form?

I have a many to many field ConnectedTo in my model and I want to create the object using a form. However when I list it as a field I just get a listbox with options to highlight and no way of selecting one or more.
Ideally I'd love a multiple selection checkbox with a list of items in a scroll box. But I'd start with just having a selectable item.
Here's my code so far:
models.py:
class Part(models.Model):
PartID = models.AutoField(primary_key=True, unique=True)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE, null=True)
Comment = models.CharField(max_length=255, blank=True)
Subtype = models.ForeignKey('Subtype', on_delete=models.CASCADE, null=True)
Location = models.CharField(max_length=255, blank=True)
ConnectedTo= models.ManyToManyField('self', blank=True, null=True)
BatchNo = models.CharField(max_length=32, blank=False, null=True)
SerialNo = models.CharField(max_length=32,blank=True)
Manufacturer = models.CharField(max_length=32, blank=False, null=True)
Length = models.CharField(max_length=6, blank=True, null=True)
InspectionPeriod = models.IntegerField(blank=True, null=True)
LastInspected = models.DateField(blank=True, null=True)
InspectionDue = models.CharField(max_length=255, blank=True)
#classmethod
def create(cls, siteid, comment, subtype, location, batchno, serialno, manufacturer, length, inspectionperiod, lastinspected, inspectiondue):
part = cls(SiteID = siteid, Comment = comment, Subtype = subtype, Location = location, BatchNo = batchno, SerialNo = serialno, Manufacturer = manufacturer, Length = length, InspectionPeriod = inspectionperiod, LastInspected = lastinspected, InspectionDue = inspectiondue)
return part
def __str__(self):
return str(self.PartID)
forms.py:
class PartForm(forms.ModelForm):
class Meta:
model = Part
fields = ('Comment', 'Subtype', 'Location', 'ConnectedTo', 'BatchNo', 'SerialNo', 'Manufacturer', 'Length', 'InspectionPeriod', 'LastInspected')
views.py:
#login_required(login_url='/accounts/login/')
def addPartForm_Create(request, site, subtype):
siteselected = site
subtypeselected = Subtype.objects.get(SubtypeID = subtype)
if request.method == 'POST':
form = addPartForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.SiteID = Site.objects.get(SiteID = siteselected)
obj.Subtype = subtypeselected
obj.save()
return redirect('/sites/'+str(site))
else:
form = addPartForm()
return render(request, 'myproj/addPart.html', {'form': form, 'SiteNo': Site.objects.get(SiteID = siteselected).SiteID, 'subtype': subtypeselected})
EDIT: had the wrong view, sorry.
EDIT 2: example of what I mean by the highlighted box:
UPDATE:
Jey_Jen's answer has helped me get the style I want. I now have a multiple selection checkbox. But the ConnectedTo attributes do not save. Everything else in the model is saved and a new part is created. But no many to many links.
I would suggest looking into django form widgets. you can override the default widget to be a whatever you want. you can view them here.
heres a small example the django docs give:
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)

Django Multiple classes in Model.py

I am new to Django and Python. I am trying to create a database of babysitters and one of the objects which can have multiple fields is Education. My first Babysitter has 2 qualifications which produces an error an will not display.
Error Message
views.py
from django.shortcuts import render, get_object_or_404, get_list_or_404
from .models import Babysitter, Education, Work, Reference
# Create your views here.
def all_babysitters(request):
babysitters = Babysitter.objects.all()
return render(request, "babysitters.html", {"babysitters": babysitters})
def babysitter_profile(request, id):
"""A view that displays the profile page of a registered babysitter"""
babysitter = get_object_or_404(Babysitter, id=id)
reference = get_object_or_404(Reference)
education = get_object_or_404(Education)
return render(request, "babysitter_profile.html", {'babysitter': babysitter, 'education': education, 'reference': reference} )
models.py
from django.db import models
from datetime import datetime
# Create your models here.
class Babysitter(models.Model):
list_display = ('firstName', 'lastName', 'minderType')
firstName = models.CharField(max_length=50, blank=True, null=True)
lastName = models.CharField(max_length=50, blank=True, null=True)
minderType = models.CharField(max_length=50, blank=True, null=True)
image = models.ImageField(upload_to='images')
phone = models.CharField(max_length=20, blank=True, null=True)
email = models.CharField(max_length=50, blank=True, null=True)
address1 = models.CharField(max_length=100, null=True)
address2 = models.CharField(max_length=100, null=True)
city = models.CharField(max_length=20, null=True)
county = models.CharField(max_length=100, null=True)
eircode = models.CharField(max_length=7, null=True)
biography = models.TextField(max_length=280,blank=True)
def __str__(self):
return self.firstName + ' ' + self.lastName
class Education(models.Model):
babysitter = models.ForeignKey(Babysitter)
school = models.CharField(max_length=50)
qualification = models.CharField(max_length=50)
fieldOfStudy = models.CharField(max_length=50)
dateFrom = models.DateField(auto_now=False, auto_now_add=False)
dateTo = models.DateField(
auto_now=False, auto_now_add=False, null=True, blank=True)
current = models.BooleanField(default=False)
graduated = models.BooleanField(default=False)
def __str__(self):
return self.school
class Work(models.Model):
babysitter = models.ForeignKey(Babysitter)
family = models.CharField(max_length=50)
role = models.CharField(max_length=50)
location = models.CharField(max_length=50)
dateFrom = models.DateField(auto_now=False, auto_now_add=False)
dateTo = models.DateField(
auto_now=False, auto_now_add=False, null=True, blank=True)
current = models.BooleanField(default=False)
def __str__(self):
return self.work
class Reference(models.Model):
babysitter = models.ForeignKey(Babysitter)
refFamily = models.CharField(max_length=50)
contact = models.CharField(max_length=50)
location = models.CharField(max_length=50)
email = models.CharField(max_length=50, blank=True, null=True)
reference = models.CharField(max_length=300)
date = models.DateField(auto_now=False, auto_now_add=False)
def __str__(self):
return self.refFamily
Can somebody help? I am going to pull my hair out. Thanks
You aren't passing enough information into the calls to get a Reference and Education object:
babysitter = get_object_or_404(Babysitter, id=id)
reference = get_object_or_404(Reference, babysitter_id=babysitter.id)
education = get_object_or_404(Education, babysitter_id=babysitter.id)
The get_object_or_404() function is a shortcut that calls get() underneath, and get() only ever returns a single object (returning more than one will result in the Exception you are seeing).
If you want to see more than one object, then don't use the get_object_or_404 shortcut method (I find those "shortcut" methods to be ugly, personally). Instead, change it to something like:
education_qs = Education.objects.filter(babysitter_id=babysitter.id)
Then loop over that queryset to get the results:
for ed in education_qs:
# Get some data
school = ed.school
You can loop over the queryset in your HTML template, if that's easier.
Update: Here's a better answer that shows how to use querysets:
def babysitter_profile(request, id):
"""A view that displays the profile page of a registered babysitter"""
babysitter = get_object_or_404(Babysitter, id=id)
reference_qs = Reference.objects.filter(babysitter_id=babysitter.id)
education_qs = Education.objects.filter(babysitter_id=babysitter.id)
return render(request, "babysitter_profile.html", {
'babysitter': babysitter,
'education_qs': education_qs,
'reference_qs': reference_qs}
)
Then, in your HTML template, you could do something like the following to show the schools the Babysitter has attended (in a bulleted list):
<ul>
{% for ed in education_qs %}
<li>{{ ed.school }}</li>
{% endfor %}
</ul>
You could do something similar for the Reference data.
I think you should set some parameters to get a specific object, rather than get a bunch of objects.
Just do it like the first instance for get_object_or_404.
reference = get_object_or_404(Reference,id=xx)
education = get_object_or_404(Education,id=yy)
get_object_or_404 returns just 1 object. Use get_list_or_404 if babysitter has "2 qualification" to prevent exception.
babysitter = get_object_or_404(Babysitter, id=id)
education = get_list_or_404(Education, id=babysitter.id)
To prevent MultipleObjectReturned exception.

Django filter from another model

In models.py I have following models:
class Project(models.Model):
project_name = models.CharField(max_length=255, unique=True, blank=False)
def __str__(self):
return str(self.project_name)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.CharField(choices=ROLE_CHOICES, max_length=255, default='Agent')
town = models.CharField(max_length=100)
project = models.ManyToManyField(Project)
def __str__(self):
return str('Advanced user informations')
class News(models.Model):
title = models.CharField(max_length=255, blank=False)
content = HTMLField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
In my views.py I have:
def news(request):
news_list = News.objects.all().order_by('-id')
paginator = Paginator(news_list, 5)
page = request.GET.get('page')
news = paginator.get_page(page)
return render(request, 'news.html', {'news': news})
Now I want to achieve that a User can only see news for a project he participates.
Something like:
News.objects.filter(News with a project that the User is linked to)
But I am not sure what could be a valid way to solve this. Maybe someone has a tip?
What about this,
News.objects.filter(project__in=request.user.profile.project.all())
This should do it:
News.objects.filter(project__profile_set__user=request.user)

How to join results of two models in Django?

I am trying to make a user panel in which each user's profile info (like avatar, joined date, etc.) are being displayed along with their posts. Here is the view that render the threads:
def topic(request, topic_id):
"""Listing of posts in a thread."""
posts = Post.objects.select_related('creator') \
.filter(topic=topic_id).order_by("created")
posts = mk_paginator(request, posts, DJANGO_SIMPLE_FORUM_REPLIES_PER_PAGE)
topic = Topic.objects.get(pk=topic_id)
topic.visits += 1
topic.save()
return render_to_response("myforum/topic.html", add_csrf(request, posts=posts, pk=topic_id,
topic=topic), context_instance=RequestContext(request))
The Topic model is:
class Topic(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(max_length=10000, null=True)
forum = models.ForeignKey(Forum)
created = models.DateTimeField()
creator = models.ForeignKey(User, blank=True, null=True)
visits = models.IntegerField(default = 0)
And the UserProfile model:
class UserProfile(models.Model):
username = models.OneToOneField(User)
name = models.CharField(max_length=30, blank=True)
city = models.CharField(max_length=30, blank=True)
country = models.CharField(
max_length=20, choices= COUTNRY_CHOICES, blank=True)
avatar = ImageWithThumbsField(), upload_to='images', sizes=((32,32),(150,150),(200,200)), blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, blank=True)
The problem is how best to join these two tables so that userprofile fields can be displayed in topic.html along with username?
Add them to context since you already have a database relation Users and Topics.
# add this to context
topic = Topic.objects.get(pk=topic_id)
creator = topic.creator.get().profile # This pulls the user object from creator field
context['creator'] = creator # Add to context
Now you can use the 'creator' context to pull fields
<h1>{{ creator.name }}</h1>
as for the avatar, if you have your media root set in settings you simply use an
<img src="/media/images/{{ creator.avatar }}">
Oh and also you can save alot of time by using ListView and DetailView part of Django's class based views.
Sorry forgot to mention you should add a related name to your one to one,
username = OneToOneField(User, related_name='profile')

Categories

Resources