Display only creator's files - Django/Python - python

I would like to display only the pictures uploaded by the creator (user) on their individual profiles.
How would I alter my code to display that?
Thank you!
models.py:
class Photo(models.Model):
creator = models.ForeignKey(MyUser, null=False, blank=False)
category = models.ForeignKey("Category", default=1, null=True, blank=True)
title = models.CharField(max_length=30, null=True, blank=True)
description = models.TextField(max_length=120, null=True, blank=True)
image = models.ImageField(upload_to='user/photos/', null=True, blank=True)
slug = models.SlugField(null=False, blank=False)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, null=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
class Meta:
unique_together = ('slug', 'category')
ordering = ['-timestamp']
def __unicode__(self):
return "%s" %(self.creator)
def get_image_url(self):
return "%s/%s" %(settings.MEDIA_URL, self.image)
def get_absolute_url(self):
return "%s/%s" %(self.creator, self.slug)
views.py:
#login_required
def account_home(request, username):
try:
u = MyUser.objects.get(username=username)
except:
u = None
photo_set = Photo.objects.all()
context = {
"photo_set": photo_set,
"notifications": notifications,
"transactions": transactions
}
return render(request, "accounts/account_home.html", context)
.html:
{% for photo in photo_set %}
<img src="{{ photo.get_image_url }}" class='img-responsive'>
<hr/>
{% endfor %}

You have a ForeignKey to user, so you can just filter the photos by that:
photo_set = Photo.objects.filter(creator=u)
or even better use the reverse relationship:
photo_set = u.photo_set.all()
Also, never ever ever ever use a blank except statement in your code. The only exception you are expecting the get to raise is MyUser.DoesNotExist, so you should catch that only.

Related

How to render each item of a dictionary in django

I am working on a django project whereby users upload resumes and they are parsed before the results are save in user profile. I have achieved the parsing part and saved the data bu the problem is rendering the data. An example is in the skills field whereby the data is stored as a dictionary and therefore I cannot display them one at a time.
Here is my models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(default='default.jpg', upload_to='profile_images')
bio = models.TextField()
resume = models.FileField('Upload Resumes', upload_to='resumes/', null=True, blank=True,default='resume.docx')
name = models.CharField('Name', max_length=255, null=True, blank=True)
email = models.CharField('Email', max_length=255, null=True, blank=True)
mobile_number = models.CharField('Mobile Number', max_length=255, null=True, blank=True)
education = models.CharField('Education', max_length=255, null=True, blank=True)
skills = models.CharField('Skills', max_length=1000, null=True, blank=True)
company_name = models.CharField('Company Name', max_length=1000, null=True, blank=True)
college_name = models.CharField('College Name', max_length=1000, null=True, blank=True)
designation = models.CharField('Designation', max_length=1000, null=True, blank=True)
experience = models.CharField('Experience', max_length=1000, null=True, blank=True)
total_experience = models.CharField('Total Experience (in Years)', max_length=1000, null=True, blank=True)
whatsapp = models.URLField(null=True, blank=True)
facebook = models.URLField(null=True, blank=True)
twitter = models.URLField(null=True, blank=True)
linkedin = models.URLField(null=True, blank=True)
languages = models.CharField(max_length=1000, null=True, blank=True)
profession = models.CharField(max_length=100, null=True, blank=True)
nationality = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.user.username
# resizing images
def save(self, *args, **kwargs):
super().save()
img = Image.open(self.avatar.path)
if img.height > 100 or img.width > 100:
new_img = (100, 100)
img.thumbnail(new_img)
img.save(self.avatar.path)
And here is my views.py:
#login_required
def profile(request):
if request.method == 'POST':
profile_form = UpdateProfileForm(request.POST, request.FILES, instance=request.user.profile)
files = request.FILES.getlist('resume')
resumes_data = []
if profile_form.is_valid():
for file in files:
try:
# saving the file
resume = profile_form.cleaned_data['resume']
parser = ResumeParser(file.temporary_file_path())
data = parser.get_extracted_data()
resumes_data.append(data)
profile_form.instance.name = data.get('name')
profile_form.instance.email = data.get('email')
profile_form.instance.mobile_number = data.get('mobile_number')
if data.get('degree') is not None:
profile_form.instance.education = ', '.join(data.get('degree'))
else:
profile_form.instance.education = None
profile_form.instance.company_names = data.get('company_names')
profile_form.instance.college_name = data.get('college_name')
profile_form.instance.designation = data.get('designation')
profile_form.instance.total_experience = data.get('total_experience')
if data.get('skills') is not None:
profile_form.instance.skills = data.get('skills')
else:
profile_form.instance.skills = None
if data.get('experience') is not None:
profile_form.instance.experience = ','.join(data.get('experience'))
else:
profile_form.instance.experience = None
profile_form.save()
return redirect('users-profile')
except IntegrityError:
messages.warning(request, 'Duplicate resume found')
return redirect('users-profile')
profile_form.save()
messages.success(request, 'Your profile is updated successfully')
return redirect('userprofile')
else:
profile_form = UpdateProfileForm(instance=request.user.profile)
return render(request, 'user/resumeprofile.html', {'profile_form': profile_form})
#login_required
def myprofile(request, user_id):
profile = Profile.objects.get(id=user_id)
context = {'profile':profile}
return render(request, 'user/profile.html', context)
Here is my template for the profile:
<div class="mt-4">
<h5 class="fs-18 fw-bold">Skills</h5>
<span class="badge fs-13 bg-soft-blue "><p>{{user.profile.skills}}</p></span>
</div>
In the current setup, the results I am getting are as shown in the image:
A screenshot of the results being renedered
As I can see from your image, you are saving all your skills in a list. So you can try doing:
{% for skill in user.profile.skills %}
{{skill}}
{% endfor %}
If you want to print it as a list you can try it out this way:
<ul>
{% for skill in user.profile.skills %}
<li>{{skill}}</li>
{% endfor %}
</ul>

Selecting one row from Foreign Key in Django

I have the following models in Django:
class Kingdom(models.Model) :
class Meta:
ordering = ('kingdom_name', )
kingdom_name = models.CharField(max_length=128, null=True, blank=True)
def __str__(self) :
return self.kingdom_name
class Phylum_Clade(models.Model) :
class Meta:
ordering = ('phylum_name', )
phylum_name = models.CharField(max_length=128, null=True, blank=True)
kingdom = models.ForeignKey(Kingdom, on_delete=models.CASCADE, null=True)
def __str__(self) :
return self.phylum_name
class Classe_Clade(models.Model) :
class Meta:
ordering = ('classe_name', )
classe_name = models.CharField(max_length=128, blank=True, null=True)
phylum_clade = models.ForeignKey(Phylum_Clade, on_delete=models.CASCADE, null=True)
kingdom = models.ForeignKey(Kingdom, on_delete=models.CASCADE, null=True)
def __str__(self) :
return self.classe_name
class Ordre(models.Model) :
class Meta:
ordering = ('ordre_name', )
ordre_name = models.CharField(max_length=128, blank=True, null=True)
classe_clade = models.ForeignKey(Classe_Clade, on_delete=models.CASCADE, null=True)
phylum_clade = models.ForeignKey(Phylum_Clade, on_delete=models.CASCADE, null=True)
kingdom = models.ForeignKey(Kingdom, on_delete=models.CASCADE, null=True)
def __str__(self) :
return self.ordre_name
class Famille(models.Model) :
class Meta:
ordering = ('famille_name', )
famille_name = models.CharField(max_length=128, blank=True, null=True)
ordre = models.ForeignKey(Ordre, on_delete=models.CASCADE, null=True)
classe_clade = models.ForeignKey(Classe_Clade, on_delete=models.CASCADE, null=True)
phylum_clade = models.ForeignKey(Phylum_Clade, on_delete=models.CASCADE, null=True)
kingdom = models.ForeignKey(Kingdom, on_delete=models.CASCADE, null=True)
def __str__(self) :
return self.famille_name
class Binomiale(models.Model) :
class Meta:
ordering = ('binomiale', )
nom = models.CharField(max_length=128, blank=True)
name = models.CharField(max_length=128, blank=True)
binomiale = models.CharField(max_length=128, blank=True)
famille = models.ForeignKey(Famille, related_name='famille_names', on_delete=models.CASCADE, null=True)
ordre = models.ForeignKey(Ordre, related_name='ordre_names', on_delete=models.CASCADE, null=True)
classe_clade = models.ForeignKey(Classe_Clade, related_name='classe_names', on_delete=models.CASCADE, null=True)
phylum_clade = models.ForeignKey(Phylum_Clade, related_name='phylum_names', on_delete=models.CASCADE, null=True)
kingdom = models.ForeignKey(Kingdom, related_name='kingdom_names', on_delete=models.CASCADE, null=True)
image = models.ImageField(blank=False, default='no_picture.png')
img_thumbnail = models.ImageField(blank=False, default='no_picture.png')
observations = models.ManyToManyField(settings.AUTH_USER_MODEL,
through='Observation', related_name='observations')
def __str__(self) :
return self.binomiale
In Views.py I have the following code:
class Famille1(OwnerListView):
model = Binomiale
template_name = 'database/famille1.html'
template_name2 = 'database/especes.html'
def get(self, request) :
strval = request.GET.get("search", False)
if strval :
query = Q(name__icontains=strval) | Q(nom__icontains=strval)
query.add(Q(name__icontains=strval) | Q(nom__icontains=strval), Q.OR)
data_list = Binomiale.objects.filter(query).select_related().distinct().order_by('nom')[:12]
ctx = {'data_list' : data_list, 'search': strval}
return render(request, self.template_name2, ctx)
else:
if request.user.is_authenticated:
famille_list1 = Binomiale.objects.select_related("famille").distinct().order_by("famille__famille_name")[:12]
ctx = {'famille_list1' : famille_list1, 'search': strval}
return render(request, self.template_name, ctx)
In my html file I use the following code:
{% if famille_list1 %}
<div class="row row-cols-12 g-3">
{% for data in famille_list1 %}
<div class="col-sm-6 col-lg-2">
<a class="linkStyles3" href="{% url 'database:data_detail' data.id %}">{{ data.famille }}</a><br/>
<h6 style="color:black">{{ data.nom }}</h6>
<img class="img-thumbnail" src="{% get_media_prefix %}{{data.img_thumbnail}}" style="width:50%">
</div>
{% endfor %}
</div>
{% endif %}
</p>
The output of this is similar to the following sqlite3 command, and output (partial):
sqlite> select famille_name, nom, name, img_thumbnail from database_binomiale inner join database_famille on database_famille.id = database_binomiale.famille_id order by famille_id;
Apidae|Bourdon terreste|Bumble bee|BumbleBee_thumb.jpg
Apidae|Abeille à miel|Honey bee|HoneyBee_thumb.jpg
Apidae|Abeille à longue corne|Long Horned Bee|LongHornedBee_thumb.jpg
Apidae|Bourdon fébrile|Common Eastern Bumble Bee|CommonEasternBumbleBee_thumb.jpg
Ardeidae|Héron cendré|Grey heron|Heron_thumb.jpg
Simuliidae|Mouche noire|Black fly|BlackFly_thumb.jpg
Muscidae|Mouche domestique|House fly|HouseFly_thumb.jpg
Culicidae|Moustique|Mosquito|Mosquito_thumb.jpg
Culicidae|Moustiques éléphants|Elephant mosquito|ElephantMosquito_thumb.jpg
Corvidae|Grand Corbeau|Common Raven|Raven_thumb2.jpg
Corvidae|Geai bleu|Blue jay|BlueJay_thumb.jpg
Cardinalidae|Cardinal à poitrine rose|Rose-Breasted Grosbeak|Grosbeak_thumb.jpg
Cardinalidae|Cardinal rouge|Northern Cardinal|Cardinal_thumb2.jpg
Mustelidae|Loutre de rivière|North American River Otter|Otter_thumb2.jpg
Mustelidae|Hermine|Stoat|Stoat_thumb.jpg
My problem is that I do not want repeats of each class "Apidae","Cardinalidae","Mustelidae" etc. I want just a single example, with its image to be displayed. I have banged my head against a wall on this for longer than I care to admit.
Can someone help me?
Thankyou!
I think that you should query on the Famille model and thus check the nom, name, etc. of the related Binomiale model objects with:
data_list = Binomiale.objects.filter(
Q(famille_names__name__icontains=strval) | Q(famille_names__nom__icontains=strval)
).distinct()
The famille_names__ lookup is due to the value for the related_name=.. parameter [Django-doc], which does not make much sense.
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the Famille model to the Binomiale
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the famille_names relation to binomales.

TypeError: __str__ returned non-string (type NoneType). Not sure how to solve this

[![Nurse admin page[![][1]][1][models.py
from django.db import models
#Work Related aka Department and Work Shift
class Department(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return self.name
class WorkShift(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
start_datetime = models.DateTimeField(null=True, blank=True)
end_datetime = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.name
#Personel Related aka Employees and Patients
class Doctor(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Nurse(models.Model):
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
reports_to = models.OneToOneField(Doctor, default="", blank=True, null=True, on_delete=models.CASCADE)
work_shift = models.OneToOneField(WorkShift, default="", blank=True, null=True, on_delete=models.CASCADE)
def __str__(self):
return str(name)
class Patient(models.Model):
STATUS = (
('Sick', 'Sick'),
('Healing', 'Healing'),
('Cured', 'Cured'),
('Deceased', 'Deceased'),
)
name = models.CharField(max_length=200, null=True, blank=True)
description = models.TextField(blank=True, null=True)
status = models.CharField(max_length=200, null=True, blank=True, choices=STATUS)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
care = models.ForeignKey(Nurse, default="", blank=True, null=True, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return self.name
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from .models import Doctor, Nurse, Patient
from django.http import HttpResponse
# Create your views here.
def index(request):
patient = Patient.objects.all()
nurse = Nurse.objects.all()
doctor = Doctor.objects.all()
total_patient = patient.count()
sick = patient.filter(status='Sick').count()
healing = patient.filter(status='Healing').count()
cured = patient.filter(status='Cured').count()
total_nurse = nurse.count()
# if request.method == 'POST':
# form =
context = {
'patient':patient, 'nurse':nurse,
'doctor':doctor, 'total_patient':total_patient,
'sick':sick, 'healing':healing, 'cured':cured,
'total_nurse':total_nurse
}
return render(request, 'lifesaver/index.html', context)
def patient(request):
patient = Patient.objects.all()
total_patient = patient.count()
context = {
'patient':patient,
'total_patient':total_patient
}
return render(request, 'lifesaver/patient.html', context)][1]
forms.py
from django import forms
from .models import Doctor, Nurse, Patient
from django.auth.contrib.forms import UserCreationForm
class DoctorForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Doctor',
'class': 'form-control'
}
))
department = forms.ModelChoiceField(queryset=department.objects.all)
class NurseForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Nurse',
'class': 'form-control'
}
))
class PatientForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Patient'
'class': 'form-control'
}))
HTML for patient
{% extends 'lifesaver/main.html' %}
{% block content %}
<h1>SUPERSTAR</h1>
{% for patient in patient %}
{{patient.name}}
{% endfor %}
{% endblock content %}
I get this error when I go to try to add another Nurse. The URL is http://127.0.0.1:8000/admin/lifesaver/nurse/add/. Everything else behaves as expected, except the adding the Nurse part.
If I try to remove the def __str___ part, the error still displays. I believe the error lies in the:
work_shift = models.OneToOneField(WorkShift, default="",
blank=True,
null=True,
on_delete=models.CASCADE)
part since when I included that code, the error spawned. Furthermore, the code is to add a work shift to certain employees and the goal is that the employees shift will display in their profile.
How do I fix this issue?
EDIT: When accessing the HTML template, the web page behaves as expected and has no issues.
In your Nurse model replace this:
def __str__(self):
return str(Nurse.name)
with this:
def __str__(self):
return self.name

Call another model field in url django

My problem is have two models job and company and i want to get all jobs in this company
My urls.py:
url(r'^jobs/(?P<slug>[\w-]+)/$', views.job_at_company, name='job_at_company'),
My views.py:
def job_at_company(request, slug):
return render(request, 'jobs.html')
My models.py:
class Company(models.Model):
title = models.CharField(max_length=100, blank=False)
slug = models.SlugField(blank=True, default='')
city = models.CharField(max_length=100, blank=False)
contact_info = models.CharField(max_length=100, blank=False, default=0)
facebook = models.CharField(max_length=100, blank=True)
twitter = models.CharField(max_length=100, blank=True)
linkedin = models.CharField(max_length=100, blank=True)
logo = models.ImageField(upload_to="logo", default=0)
class Jobs(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True, default='')
company = models.ForeignKey(Company, on_delete=models.CASCADE)
price = models.IntegerField(default='')
Description = models.TextField(blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
job_type = models.CharField(max_length=100, choices=(('Full Time', 'Full Time'),('Part Time', 'Part Time')),default='Full Time')
in the views.py we can add this
def job_at_company(request, slug):
results = Jobs.objects.filter(company__slug=slug)
context = {'items':results}
return render(request, 'jobs.html',context)
Suppose you pass id in the url. The id is the primary key of the company. You would have to modify your url to accept id like -
url(r'^jobs/(?P<slug>[\w-]+)/(?P<pk>[\d]+)$', views.job_at_company, name='job_at_company')
And modify your views.py -
def job_at_company(request, slug, pk):
jobs_qs = Jobs.objects.filter(company__id=pk)
return render(request, 'jobs.html', {'jobs': jobs_qs})
And use it in your html like -
{% for job in jobs %}
{{job.title}}
{% endfor %}
Look at this link. Django's documentation is helpful, follow that

Django ORM - Error retreiving data -

I'm creating a page that has one video , as many comments , replies for each comment
I could retrieve video and comments but replies for each comment haven't been retrieved eventually.
I made some for loops in views file but didn't know also how to retrieve it in the templates file.
I'm stuck between views and templates till now
I'm using django 1.10.4
models.py
class Video(models.Model):
title = models.CharField(max_length=120)
embed_code = models.CharField(max_length=500)
slug = models.SlugField(null=True, blank=True)
category = models.ForeignKey("Category", null=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
active = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
free_preview = models.BooleanField(default=False)
share_message = models.CharField(max_length=150, default=default_share_message)
objects = models.Manager()
# activemodel = ActiveModel()
featuresandactive = Features()
class Meta:
unique_together = ('slug', 'category')
def __str__(self):
return self.title
def get_absolute_url(self):
try:
return reverse('video_detail', kwargs={'vid_slug':self.slug, 'cat_slug':self.category.slug})
except:
return "/"
class Comment(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(MyUser)
path = models.CharField(max_length=350)
video = models.ForeignKey(Video, null=True, blank=True)
text = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
Timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
active = models.BooleanField(default=True)
objects = CommentManager()
def __str__(self):
return self.text
class Reply(models.Model):
user = models.ForeignKey(MyUser)
comment = models.ForeignKey(Comment,null=True, blank=True)
text = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
Timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
active = models.BooleanField(default=True)
objects = ReplyManager()
def __str__(self):
return self.text
views.py
def video_detail(request, cat_slug, vid_slug):
cat = Category.objects.get(slug=cat_slug)
comments = Comment.objects.filter(video=obj)
replys = Reply.objects.filter(comment=comments)
context = {
"cat": cat,
"obj":obj,
"comments":comments,
"replys":replys,
}
return render(request, 'video_detail.html', context)
this is another view.py
I tried this also but didn't work
def video_detail(request, cat_slug, vid_slug):
cat = Category.objects.get(slug=cat_slug)
obj = Video.objects.get(slug=vid_slug)
comments = obj.comment_set.all()
Replies = Reply.objects.filter(comment_id=comments.id))
context = {
"cat": cat,
"obj":obj,
"comments":comments,
"replies":replies
}
return render(request, 'video_detail.html', context)
IMO, you can represent the comments in your template. your template may look like this.
# your_template.html
{% for comment in obj.comment_set.all %}
{{comment.user}}: {{comment.text}}
{% for reply in comment.reply_set.all %}
{{reply.user}}: {{reply.text}}
{% endfor %}
{% endfor %}
then your view function only needs cat and obj, not comments or replies. also check out select_related.

Categories

Resources