Django get_absolute_url with ForeignKey parameter not working - python

I am using the get_absolute_url method to get the url for a dynamic query, however when the link is displayed, it only shows the first parameter and not the second in the get_absolute_url method. It only does this when I use the ForeignKey of the model as the first parameter. Below is the code.
class Topic(models.Model):
topic_id = models.AutoField(primary_key=True)
forum_id = models.ForeignKey(Forum)
topic_title = models.CharField(max_length=400)
topic_date_time = models.DateTimeField(auto_now_add=True)
topic_user_id = models.IntegerField()
topic_views = models.IntegerField(default=0)
topic_replies = models.IntegerField(default=0)
topic_is_locked = models.BooleanField(default=False)
topic_is_sticky = models.BooleanField(default=False)
def __unicode__(self):
return '%s' % _(u'self.topic_title')
def get_absolute_url(self):
**return '/forums/%i/%i/' % (self.forum_id, self.topic_id)**
How can I fix this? Thanks!

def get_absolute_url(self):
return '/forums/%s/%s/' % (str(self.forum_id.pk), self.topic_id)
edit: jerzyk comment mentions these other points:
using #permalink with get_absolute_url and reversing the url using the view and arguments so you don't have to hardcode the urls.
using _id instead of .pk
def get_absolute_url(self):
return '/forums/%s/%s/' % (self.forum_id_id, self.topic_id)

Related

How to solve url parameter problem in Django?

I have a strange problem.
I have a page that uses url parameters. Users can reach this site based on their project id and name and the group(csoport) name that stored in three models. This is a link for an example page:
/performance/monthlyfeedback/{{ request.user.profile.csoport }}
That link works fine if the name of the csoport is a number. If it is any kind of a text it gives me 404 error that I can't figure out why.
models.py
class Profile(models.Model):
def __str__(self):
return str(self.user)
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
csoport = models.CharField(max_length=100, null=True, blank=True)
class Projekt_perf(models.Model):
def __str__(self):
return str(self.projekt_perf)
projekt_perf = models.CharField(max_length=250)
jogosult_01_perf = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
class Performance_profile(models.Model):
def __str__(self):
return str(self.user_name)
user_name = models.ForeignKey(User, on_delete=models.CASCADE)
projekt_perf = models.ForeignKey(Projekt_perf,on_delete=models.CASCADE)
views.py
I am using raw query in the views.
def obj_results(request, projekt_perf_id, projekt_perf, user_name_id, csoport):
person = Projekt_perf.objects.raw('SELECT * FROM performance_projekt_perf INNER JOIN performance_performance_profile ON performance_projekt_perf.id = performance_performance_profile.projekt_perf_id INNER JOIN stressz_profile ON performance_performance_profile.user_name_id = stressz_profile.user_id WHERE performance_projekt_perf.id = %s AND projekt_perf = %s AND stressz_profile.user_name_id = %s AND stressz_profile.csoport = %s',[projekt_perf_id, projekt_perf, user_name_id, csoport])
context = {
'person': person,
}
return render(request, 'performance/obj-results.html', context)
urls.py
app_name = 'performance'
urlpatterns = [
path('monthlyfeedback/<int:projekt_perf_id>', login_required(views.Performance_test), name='performance_feedback'),
path('list/<int:projekt_perf_id>/<projekt_perf>', login_required(views.list), name='performance_list'),
path('obj-results/<int:projekt_perf_id>/<projekt_perf>/<int:user_name_id>/<csoport>', login_required(views.obj_results), name='obj_results'),
]
What am I doing wrong?
In urls.py:
path('monthlyfeedback/<int:projekt_perf_id>'
You have defined the “project_perf_id” as int. Change it.
Can you try with <str:csoport> but I reccomend you to use slugs.
path('obj-results/<int:projekt_perf_id>/<projekt_perf>/<int:user_name_id>/<str:csoport>', login_required(views.obj_results), name='obj_results'),

if-else statement in python django

I am new to Django and I have a problem that I couldn't solve. I am trying to display a specific question and other related attribute from my Question model based on a field from the Participant model. The issue here is that it directly goes to the else statement even when the condition is true.I tried to print(participant.condition) and it works so I am not sure why its not working with the if statement.
#login_required
def LPSC_VIEW1(request):
participant=request.user.participant
if participant.condition == 'LPN':
First_question= Question.objects.get(id=1)
all_choices = First_question.choices.all()
context = {'First_question': First_question, 'all_choices': all_choices}
return render(request, 'study/FirstQN.html', context)
else:
First_question= Question.objects.get(id=12)
all_choices = First_question.choices.all()
context = {'First_question': First_question, 'all_choices': all_choices}
return render(request, 'study/FirstQSC.html', context)
my models as the following:
class Question(models.Model):
question_text = models.CharField(max_length=200)
caption = models.CharField(max_length=200, default="this is a caption")
choices = models.ManyToManyField(Choice)
vis_image = models.ImageField(default= "this is an image", null=False, blank=False, upload_to="static/study/img")
def __str__(self):
return self.question_text
class Condition(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Participant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
condition = models.ForeignKey(Condition, on_delete=models.CASCADE)
score = models.IntegerField(default=0)
def __str__(self):
return self.user.username
condition is a foreign key, not a string. You're comparing it against 'LPN', but no instance of your Condition model will be equal to that string.
Try if participant.condition.name == 'LPN': to compare the name field on the Condition instance to that string.
Your print statement shows them as apparently being the same because you've defined how to present Condition instances as strings with your __str__ method - it will print the name for the Condition instance, but that doesn't mean that the Condition value is actually equal to that string.
You must change this:
participant=request.user.participant
to:
participant=Participant.objects.get(user=request.user)
You might have to use
from .models import Participant
participant = Participant.objects.get(user = request.user)

NOT NULL constraint failed: portal_visitrequests.visitor_id

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 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

Django View Counter

What is the best way to make view counter function in my views.py ?
I did find F() expressions in Django documentation , but how to make it work or any better idea?
Thank you in advance
def watch_video(request, slug):
video = get_object_or_404(Video, slug=slug)
template = "single_video.html"
#if this function will run , + 1 in Video.views ?
return render(request,template,{"video":video})
my model:
class Video(models.Model):
video_id = models.CharField(max_length=150)
title = models.CharField(max_length=150)
slug = AutoSlugField(populate_from="title")
description = models.TextField(blank=True)
views = models.PositiveIntegerField(default=0)
likes = models.PositiveIntegerField(default=0)
category = models.ForeignKey("VideoCategory")
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
tags = models.ManyToManyField("Tag")
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("watch", kwargs={"slug" : self.slug})
Call the update() on the queryset which filters the single video:
from django.db.models import F
Video.objects.filter(pk=video.pk).update(views=F('views') + 1)
video.views += 1 # to show valid counter in the template
It's very simple make an increase function in model which increment views by 1
Then in views.py call that increase function everytime a user visits that model's page and save it!

Categories

Resources