NOT NULL constraint failed: portal_visitrequests.visitor_id - python

I am very new to django and I've been battling with this particular project for a while now. I get a not null constraint error every time I try and submit my form(which ultimately creates Visitor and VisitRequests objects). The error comes from this line of code...visit_request = VisitRequests(staff=staff, visitor=visitor, comment=comment, token=token, status=None).save()... Please view the code below.
views.py
def formpage(request):
if request.method=='POST':
token=secrets.token_urlsafe(20)
visitor_name=request.POST.get('visitorsname')
comment=request.POST.get('comment')
visit_type=request.POST.get('visit_type')
visit_content='You have a waiting visitor'+'\n'+'Name:'+visitor_name+'\n'+'Purpose Of Visit:'+visit_type+'\n'+'Additional Comment:'+comment+'\n'+token
staff_id=request.POST.get('staff')
staff=Staff.objects.get(id=staff_id)
staff_email=staff.staff_email
req_comment = request.POST.get('req_comment')
request_id = (request.POST.get('request_id'))
visitor=Visitor(visitor_name=visitor_name).save()
visit_request = VisitRequests(staff=staff, visitor=visitor, comment=comment, token=token, status=None).save()
models.py
class Staff(models.Model):
staff_name = models.CharField(max_length=250)
staff_email = models.CharField(max_length=250, default="")
def __str__(self):
return self.staff_name
class Visitor(models.Model):
visitor_name = models.CharField(max_length=250)
timestamp = models.DateTimeField(default=timezone.now)
def __str__(self):
return '{}'.format(self.visitor_name)
class VisitRequests(models.Model):
staff=models.ForeignKey(Staff, on_delete=models.CASCADE)
visitor = models.ForeignKey(Visitor, on_delete=models.CASCADE)
comment= models.TextField(default='')
status= models.NullBooleanField()
token=models.CharField(max_length=20)

Your implementation is assuming Django's save returns the model object, which is not the case. You may want to read Why does django ORM's save method not return the saved object? for further understanding.
In your case you can use Django's create function to create and get the returned object:
visitor = Visitor.objects.create(visitor_name=visitor_name)
visit_request = VisitRequests.objects.create(staff=staff, visitor=visitor, comment=comment, token=token, status=None)

Related

Django: How to write a function based view used for URL with parameter

I am learning Django, using function based views, and I am struggling with the following:
I have this path in urls.py
path('user/<str:username>',views.UserProjectList,name='user-projects')
that is supposed to show all the projects of the particular user (client). In order to reach it, username should be parameter of the function based view, however I am struggling how to write such view...
I have this:
def UserProjectList(request,username):
user = User.objects.get(username=username) #THIS IS WRONG and should return id of the user
#user = User.objects.filter(username=username) #also wrong
tag_list = ProjectTagsSQL.objects.all() #ProjectTagsSQL and ProjectSQL are connected
project_list = ProjectSQL.objects.filter(client=user) #ProjectSQL table has column client_id (pk is id in User) and table contains all the projects
context = {
'tagy' : tag_list,
'projecty' : project_list
}
return render(request, 'home_page/user_projects.html', context) #SHOULD THE PARAMETER BE INCLUDED HERE?
I tried to inspire with the code from class based view I found on the internets (thats is working for me but i didnt manage to connect it with ProjectTagsSQL as i managed in FBV, but that's a different problem) but i didnt manage
class UserProjectListView(ListView):
model = ProjectSQL
template_name = 'home_page/user_projects.html'
context_object_name = 'data'
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return ProjectSQL.objects.filter(client=user)
Could someone help me how to deal with such function based view please? As this solution its not working (will return nothing for any user)
Here is also the ProjectSQL model (and ProjectTagsSQL model) :
class ProjectSQL(models.Model):
id = models.AutoField(primary_key=True)
country = models.TextField()
city = models.TextField()
time_added = models.DateTimeField(default=timezone.now)
start_date = models.DateField()
end_date = models.DateField()
client = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
managed = False #https://docs.djangoproject.com/en/4.0/ref/models/options/
db_table = 'project'
class ProjectTagsSQL(models.Model):
id = models.IntegerField(primary_key=True)
project = models.ForeignKey(ProjectSQL, on_delete=models.CASCADE)
tag = models.ForeignKey(ProjectTagSQL, on_delete=models.CASCADE)
class Meta:
managed = False # https://docs.djangoproject.com/en/4.0/ref/models/options/
db_table = 'project_tags'
You need to write user.id so:
from django.shortcuts import get_object_or_404
def UserProjectList(request,username):
user = get_object_or_404(User,username=username)
tag_list = ProjectTagsSQL.objects.all()
project_list = ProjectSQL.objects.filter(client=user.id)
context = {
'tagy' : tag_list,
'projecty' : project_list
}
return render(request, 'home_page/user_projects.html', context)
Also, try to check template variables' name, whether you used same or not.
Note: Always append / at the end of every route so it should be path('user/<str:username>/'....
Note: Function based views are generally written in snake_case so it is better to name it as user_project_list instead of UserProjectList.

null value in column "job_id" violates not-null constraint

I'm trying to upload a pdf file but I keep getting an integrity error, when I try to submit the pdf file, it looks like I have some blank space in the DB which I don't know, may someone please help me! The error is:
IntegrityError at /posts/resume/
null value in column "job_id" violates not-null constraint
models.py
class Jobs(models.Model):
title = models.CharField(max_length=80)
jobs_type = models.CharField(max_length=80, choices=JOB_CHOICES)
description = models.TextField()
requirements = models.TextField()
posted_date = models.DateTimeField(auto_now_add=True)
start_date = models.DateField()
deadline = models.DateField()
link = models.URLField()
slug = models.SlugField(max_length=150)
contacts = models.CharField(max_length=80)
tags = TaggableManager()
class Meta:
ordering = ('-posted_date',)
class Application(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name="application",
on_delete=models.CASCADE)
job = models.ForeignKey(Jobs, on_delete=models.CASCADE)
professional_summary = models.TextField()
resume = models.CharField(max_length=150)
uploaded_at = models.DateTimeField(auto_now_add=True)
form.py
class ApplicationForm(forms.ModelForm):
resume = forms.FileField(widget=forms.FileInput(attrs={'onchange': 'uploadPreview(this)'}))
oss_resume = forms.CharField (widget=forms.HiddenInput(), required=False)
class Meta:
model = Application
fields = ('professional_summary', 'resume', )
views.py
class CreateApplicationView(LoginRequiredMixin, CreateView):
form_class = ApplicationForm
model = Application
message = _("Your Event has been created.")
success_url = reverse_lazy('posts:list_jobs')
def __init__(self, **kwargs):
self.object=None
super().__init__(**kwargs)
def form_valid(self, form):
resume = form.cleaned_data['oss_resume']
form.instance.user = self.request.user
submit = form.save()
submit.user= self.request.user
if not resume:
return ('posts/no_resume.html')
else:
submit.save()
def get_success_url(self):
messages.success(self.request, self.message)
return reverse('posts:list_events')
def get_object(self):
resume = kwargs.get('resume')
return Application.objects.get(resume=resume)
urls.py
url(r'^list-jobs/$', JobsListView.as_view(), name='list_jobs'),
url(r'^resume/$', CreateApplicationView.as_view(), name='resume'),
the results is
IntegrityError at /posts/resume/
null value in column "job_id" violates not-null constraint
DETAIL: Failing row contains (7, first job , processing.pdf, 2019-07-10 11:40:06.873356+00, null, null).
Your Application model has a ForeignKey to Jobs model (which I think should be just Job, but that's another matter), but it is not nullable/blank. It seems to me your view does not provide a Jobs instance to the Application instance that's being created with the PDF upload, hence the error.
Update:
One way of doing this would be to add null=True, blank=True to your job field declaration on the Application model. However, this doesn't sound like a good solution, as an application should be associated to a job. So you need to allow the user to pick the job that he's applying to in the Application form or automatically assign that job to the application when you process the form submission in the CreateApplicationView.
Update 2:
In your ApplicationForm, try to do this:
class ApplicationForm(forms.ModelForm):
resume = forms.FileField(widget=forms.FileInput(attrs={'onchange': 'uploadPreview(this)'}))
oss_resume = forms.CharField(widget=forms.HiddenInput(), required=False)
job = forms.ModelChoiceField(queryset=Jobs.objects.all())
class Meta:
model = Application
fields = ('professional_summary', 'resume', 'job')
I've added the field in the form for the person to pick the Job he/she's applying for. This should fix the error or push you in the right direction.

How to update a manytomany field in Django without deleting the previous object?

I have seen this question before, but mine is a bit more restricted in terms of getting the object and filtering.
EDIT - Removed relationship between member and title and changed member and xmlgraph to one to many relationship
I have these classes in models.py:
class Title(models.Model):
title = models.TextField(null=True)
def __str__(self):
return self.title
class XMLGraph(models.Model):
#only one title per graph
title = models.OneToOneField(
to=Title,
blank=True,
null=True,
on_delete=models.CASCADE)
XMLGraph = models.TextField(null=True)
def __str__(self):
return str(self.XMLGraph)
class Member(User):
XMLGraph = models.ForeignKey('XMLGraph',
null=True,
on_delete=models.CASCADE)
def __str__(self):
return self.username
class Profile(models.Model):
user = models.OneToOneField(
to=Member,
blank=True,
null=True,
on_delete=models.CASCADE
)
def __str__(self):
return self.name
One Member can store multiple XMLGraphs which are basically text files stored in the database. I have a functionality where the user can save and save as the XMLGraph.
The save function should create a new object of the XMLGraph if there is nothing in the database or update the current XMLGraph. So, when the user presses save, it should update the data stored in the XMLGraph. So, I took this approach:
Save function in views.py
def saveData(request, user):
if request.method == "POST":
xmlData = request.POST['xml']
member = Member.objects.get(username=user)
XMLGraph.objects.all().delete()
xml, _ = XMLGraph.objects.get_or_create(XMLGraph = xmlData)
member.XMLGraph.add(xml)
return render_to_response("fastcookapp/index.html", content_type="text/xml;")
return HttpResponse('POST is not used')
However, now the issue is that the Save As function should generate a new object for XMLGraph and Title which works fine, but once they click the save function it will delete the previous data for XMLGraph because of the following line in saveData
XMLGraph.objects.all().delete()
Save As in views.py:
#loggedin
def saveAs(request, user):
if request.method == "POST":
member = Member.objects.get(username=user)
graphTitle = request.POST['title']
title = Title.objects.create(title=graphTitle)
member.title.add(title)
xmlData = request.POST['xml']
xml = XMLGraph.objects.create(XMLGraph = xmlData, title=title)
member.XMLGraph.add(xml)
return render_to_response("fastcookapp/index.html", content_type="text/xml;")
return HttpResponse('POST is not used')
I am aware of .remove() being used instead of delete, but it doesn't seem to work properly as I can't remove the previous data that was added when the user presses save.

conflict with post save and __unicode__(self) in django models

Apologies for the strange title, but caught on a funny problem involving a conflict with post.save (from a form) and the unicode(self) return in my model.
Models.py
class NumericTraits(models.Model):
feature_id = models.IntegerField(primary_key=True)
species = models.ForeignKey('Species')
traits = models.CharField(max_length=30)
cite = models.ForeignKey(Citation)
username = models.CharField(max_length=30)
dt = models.CharField(max_length=30)
def __unicode__(self):
return self.species_id + self.traits + self.cite_id
class Meta:
db_table = 'numeric_traits'
verbose_name = "Numeric Traits"
verbose_name_plural = "Numeric Traits"
class Citation(models.Model):
cite_id = models.CharField(primary_key=True, max_length=25, default=citation_id_create)
citation_name = models.CharField(max_length=100)
citation = models.TextField()
def __unicode__(self):
return self.citation_name
class Meta:
managed = False
db_table = 'citation'
ordering = ['citation_name']
views.py
def dbPost(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save( commit = False)
citeId = request.POST.get("citation", "")
post.cite_id = Citation.objects.get(cite_id = citeId)
post.save()
return render(request, 'app/SaveSuccess.html')
else:
form = PostForm()
In this case, I'm posting a value of (for example) 'citation1' - which refers to the primary key I"m using here. I use "self.citation_name" (which is "Ainley et al 1995) to display an intuitive name in the django admin.
however, when I go to save, this just gives me an error (e.g., cite_id = Ainley et al 1995 does not exist).
So, it's taking the value of self.citation_name and returning it, then attempting to find the cite_id that matches. However, I want it to return the cite_id value, locate the record, while maintaining the self.citation_name in my model so I can read the admin records easier.
Any help is greatly appreciated
Thanks
of course... always something simple.. I guess when I was trying to assign "post.cite_id", it was trying to assign it to the foreign key in a funny way.. Fixed this by changing.
post.cite_id = .....
to
post.cite = .....

Related Field got invalid lookup: icontains

I am trying to include a search field inside my home page. It works for some of the module field. My problem is when I use a ForeignKey field (correct me please if I am wrong).
models.py
class Location(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
my_location = models.CharField(max_length=120, choices=LOCATION_CHOICES)
update_date = models.DateField(auto_now=True, null=True)
def __str__(self):
return self.my_location
class UserProfile(models.Model):
user = models.ForeignKey(User)
# The additional attributes we wish to include.
user_base = models.CharField(max_length=120, choices=LOCATION_CHOICES)
user_position = models.CharField(max_length=120)
user_phone = models.PositiveIntegerField()
def __unicode__(self):
return self.user.username
views.py
def search_by_location(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
locations = Location.objects.filter(my_location__icontains=q).order_by('-update_date')
else:
locations = Location.objects.order_by('-update_date')
context = {'locations': locations}
return render(request, 'index.html', context)
My problem is if I use user inside the filter query instead of my_location I receive the error:
Related Field got invalid lookup: icontains
Please any advice on how to troubleshoot or any documentation I can read.
You can use icontains lookup on text fields. user is related (integer) field. Instead of user use user__username.
locations = Location.objects.filter(user__username__icontains=q)
class SearchView(ListView):
model = Profile
template_name = 'blog/search_results.html'
context_object_name = 'all_search_results'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_name = self.request.GET.get('search', '')
context['all_search_results'] = Profile.objects.filter(user__username__icontains=user_name )
return context
here is another example on how to filter objects. if searching for a user, remember to user user_username__icontains=user_name
also remember that if you use Profile your'll get a different id than if you use User

Categories

Resources