display foreignkey field in django template - django

I have models.py like below:
class Profile(models.Model):
user = models.OneToOneField(User)
def __unicode__(self):
return "%s" % self.user
class Student(models.Model):
user = models.ForeignKey(Profile)
phone_num = models.CharField(max_length=15)
def __unicode__(self):
return "%s" % (self.user)
class Teacher(models.Model):
user = models.ForeignKey(Profile)
phone_num = models.CharField(max_length=15)
def __unicode__(self):
return "%s" % (self.user)
class Complaint(models.Model):
user = models.ForeignKey(Student)
complaint = models.TextField()
teacher = models.ForeignKey(Teacher, null=True)
def __unicode__(self):
return "%s : %s" % (self.complaint)
How can I display teacher's name which is eventually stored in class Profile
What I get is a column teacher_id in _complaint table when I do
student_obj = Student.objects.get(name=user_profile_instance)
and then
compaint = student_obj.complaint_set.values()
in complaint.html
{{complaint.teacher_id}}
what I want is teacher name instead of id

This should work -
{{ complaint.teacher.user.user.first_name }}

First of all Please Update your style of coding to make your App Optimised
Use
student_obj = Student.objects.select_related().get(name=user_profile_instance)
The Above one will Cache Datas . After that each time when u call Datas from fields it Wont HIT your database :) , Hence Your App will Fly
instead of
student_obj = Student.objects.get(name=user_profile_instance)
and i'm Agreeing with #Bibhas Answer
{{ complaint.teacher.user.user.first_name }}
Teacher's Profile is Inheriting Django's Auth Model User
That wise
user.user.first_name

Related

Count how many posts a user liked in Django

I would like to create a variable that I can pass through as context which will count
how many posts a user liked.
Here is my models.py
class post(models.Model):
title = models.CharField(max_length = 255)
title_tag=models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete = models.CASCADE)
body = models.TextField()
post_date = models.DateTimeField(auto_now_add=True)
category = models.CharField(max_length=255, default = "coding")
likes = models.ManyToManyField(User, related_name='blog_posts')
def __str__(self):
return self.title + ' | ' + str(self.author) + ' | ' + str(self.category)
def get_absolute_url(self):
from django.urls import reverse
return reverse('article-detail',args=[self.id] )
def total_likes(self):
return self.likes.count()
Here is my views.py
class ArticleDetailView(DetailView):
model = post
template_name = 'article_details.html'
def get_context_data(self,*args,**kwargs):
cat_menu = Category.objects.all()
#amount_of_user_likes = ????
context = super(ArticleDetailView,self).get_context_data(*args,**kwargs)
'''context allows us to access these values on our page'''
stuff=get_object_or_404(post,id=self.kwargs['pk'])
total_likes= stuff.total_likes()
liked = False
if stuff.likes.filter(id=self.request.user.id).exists():
liked = True
context['cat_menu'] = cat_menu
context['total_likes']=total_likes
context['liked'] = liked
context['amount_of_user_likes']=amount_of_user_likes
return context
I am not sure how to query the Database in order to get the amount of posts that a user liked since the liked column is on the post table and not on the user table. However, since it is a many to many relationship then we can access the user somehow but I am unsure.
You can count the number of times myuser liked a post with:
myuser.blog_posts.count()
so if you want to do that for the logged in user, we can work with:
context['amount_of_user_likes'] = self.request.user.blog_posts.count()

Display full names in Form ChoiceField but saving ID's

I have model Person - from another database
I copied all person_id to custom_id.
models.py
class Employee(models.Model):
custom_id = models.CharField(max_length=20, unique=True)
#property
def person(self):
return Person.objects.get(person_id='%s' % self.custom_id)
def __str__(self):
return '%s' % self.custom_id
class Task(models.Model):
employee = models.ManyToManyField(Employee, blank=True, null=True)
task = models.CharField(max_length=100)
comment = models.CharField(max_length=200)
def __str__(self):
return '%s' % self.task
I add my method person() to Employee which allow me to access other objects model in another database:
So basically when I type this in shell:
Employee.objects.get(custom_id='123').person.full_name
u'Adam Dylan'
I have a ModelForm which use ModelMultipleChoiceField
forms.py
class TaskCreateForm(forms.ModelForm):
employee = forms.ModelMultipleChoiceField(queryset=Employee.objects.all())
class Meta:
model = Task
But Employee.objects.all() returns bunch of custom_id's.
What I want is to show in form "Employee(..).person.full_name" but saving only custom_id's.
I am not sure why you think the answer I gave to your other question does not work here. Did you try the following? If it does not work, how exactly does it fail?
class EmployeeMultipleChoiceField(ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.person.full_name
class TaskCreateForm(forms.ModelForm):
employee = EmployeeMultipleChoiceField(queryset=Employee.objects.all())
class Meta:
model = Task

Django createview using primary key

I have a model like this:
class Appointment(models.Model):
user = models.ForeignKey(User)
engineer = models.ForeignKey(Engineer)
first_name = models.CharField(max_length=100)
middle_name = models.CharField(max_length=100, blank=True)
last_name = models.CharField(max_length=100)
age = models.IntegerField()
def __unicode__(self):
return self.first_name
I have created a form using this model and I want to save it. Here I want the 'engineer' field to to be as the primary key is passed in the url.. like
engineer = Engineer.objects.get(pk=pk)
How can I do this. Or I should create a normal form and get its value via get method and assign to the field??
Since this is a CreateView, you should build on the example in the documentation and add it in form_valid:
def form_valid(self, form):
form.instance.engineer = Engineer.objects.get(pk=self.kwargs['pk'])
return super(AppointmentCreate, self).form_valid(form)

Django 1.5 ModelForm like admin in view with images and foreign key

I have the following models:
class Quiver(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
is_default = models.BooleanField(default=False)
type = models.CharField(max_length=1, choices=QUIVER_TYPES)
category = models.CharField(max_length=255, choices=QUIVER_CATEGORIES)
def __unicode__(self):
return u'[%s] %s %s quiver' % (
self.user.username,
self.get_type_display(),
self.get_category_display())
class Image(models.Model):
photo = models.ImageField(upload_to=get_upload_file_path)
is_cover = models.BooleanField(default=False)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
def save(self, *args, **kwargs):
try:
this = Image.objects.get(pk=self.pk)
if this.photo != self.photo:
this.photo.delete(save=False)
except Image.DoesNotExist:
pass
super(Image, self).save(*args, **kwargs)
class Surfboard(models.Model):
quiver = models.ForeignKey(Quiver)
brand = models.CharField(max_length=255)
model = models.CharField(max_length=255)
length = models.CharField(max_length=255)
width = models.CharField(max_length=255, blank=True)
thickness = models.CharField(max_length=255, blank=True)
volume = models.CharField(max_length=255, blank=True)
images = generic.GenericRelation(Image)
def __unicode__(self):
return u'%s %s %s' % (self.length, self.brand, self.model)
def get_cover_image(self):
"Returns the cover image from the images uploaded or a default one"
for image in self.images.all():
if image.is_cover:
return image
return None
I'd like to be able to have the same form I have in the admin in my frontend view /surfboard/add:
As a new Django fan and user, I started to create the form from scratch. Not being able to do what I want with including the foreign key "quiver" as a dropdown list, I found in the doc the ModelForm, and decided to use it, so here what I got:
class SurfboardForm(ModelForm):
class Meta:
model = Surfboard
In my view, it looks like this and it's already a good start:
So now, I wanted to have a way to add pictures at the same time, and they are linked to a surfboard via a Generic Relation. Here I don't find the way to do a implementation like in the admin, and get frustrated. Any tips to do so?
Thanks!
What you seek is called an inline formset - see the docs for more.
It's also handy that you can render a formset quickly with {{ formset.as_p }}, but you'll need to write some JavaScript (or use the JavaScript that's used in the Django admin) to handle adding and removing forms.

insert json data into MySQL database

1.I want to save data from database(mysql) to .json file format.
Models.py
class Author(models.Model):
author_id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
age=models.IntegerField()
class Meta:
db_table=u'Author'
def __unicode__(self):
return u"%d %s %s %s %d" % (self.pk, self.first_name, self.last_name, self.email,self.age)
class Book(models.Model):
book_id=models.AutoField(primary_key=True,unique=True)
book_name=models.CharField(max_length=30)
publisher_name=models.CharField(max_length=40)
author=models.ForeignKey(Author)
class Meta:
db_table = u'Book'
def __unicode__(self):
return u'%d %s %s' % (self.pk, self.book_name, self.publisher_name)
views.py is
def addbook(request):
log.debug("test....")
if request.POST:
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
email = request.POST.get('email')
age = request.POST.get('age')
author = Author(first_name = first_name,last_name = last_name,email=email,age=age)
author.save()
book_name = request.POST.get('book_name')
publisher_name = request.POST.get('publisher_name')
author_info = Author.objects.latest('author_id')
log.debug("test:%s",author_info.author_id)
book=Book(book_name=book_name,publisher_name=publisher_name,author_id=author_info.author_id)
book.save()
return redirect('/index/')
else:
return render_to_response('addbook.html',context_instance=RequestContext(request))
1) In views.py an addbook function is used to add the related data to database.
2) I have to store the database content to a json file after each entry.
3) Can i get help to code the same.
This link explains how to serialize Django models. You will have to add something like this to your model code:
from django.core import serializers
class Book(models.Model):
...
def serialize(self):
JSONSerializer = serializers.get_serializer("json")
json_serializer = JSONSerializer()
with open("/path/to/file/file.json", "w") as out:
json_serializer.serialize([self], stream=out)
The square brackets around [self] are important if you want to serialize a particular instance of a model. If you are serializing a queryset then you can pass that in instead.