I'm using the 'through' argument to connect Bot to Developer through Development team, in my html page (home.html), how would I render Developer's name in DevelopmentTeam? Also, I've tried to simply render the DevelopmentTeam name and was unsuccessful as well. I would greatly appreciate if someone could guide me in the right direction as I've read documentation everywhere and the issue persists.
thanks all in advance!
home.html
{% for bot in bot_list_slice|slice:":5" %}
<div class="col">
<a href="{% url 'bot_detail' bot.slug %}" class="text-decoration-none">
<div class="row-inside-content">
<div class="container">
<img src="#">
<h6 class="text-dark">{{ bot.bot_name|title }}</h6>
</div>
<div class="container">
<span class="badge bg-light text-dark">Software</span>
</div>
<div class="container">
<p>{{ bot.team_members.name **<here>** }}</p>
</div>
</div>
</a>
</div>
{% endfor %}
Models.py
class Developer(models.Model):
name = models.CharField(max_length=20, blank=False)
profile = models.ImageField(blank=True,null=True)
job_choices = [
('Backend Developer', 'Backend Developer'),
('Frontend Developer', 'Frontend Developer'),
('Lead Developer', 'Lead Developer'),
('Team Developer', 'Team Developer'),
('Designer', 'Designer'),
]
job = models.CharField(choices=job_choices, max_length=20)
team = models.ManyToManyField('DevelopmentTeam', blank=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Developer, self).save(*args, **kwargs)
def __str__(self):
return '{}'.format(self.name)
class DevelopmentTeam (models.Model):
team_name = models.CharField(max_length=20, null=True)
members = models.ForeignKey(Developer,on_delete=models.CASCADE, null=True)
bot = models.ForeignKey("Bot", on_delete=models.CASCADE, null=True)
def __str__(self):
return '{} '.format(self.team_name, self.members, self.bot)
class Bot(models.Model):
bot_name = models.CharField(max_length=20, blank=False, null=True)
company_logo = models.ImageField(blank=True, null=True)
team_members = models.ManyToManyField(Developer, through=DevelopmentTeam, blank=True)
slug = models.SlugField(max_length=50, null=True, blank=True, unique=True)
def __str__(self):
return '{}, {}'.format(self.bot_name, self.admin_approval)
def save(self, *args, **kwargs):
self.slug = slugify(self.bot_name)
super(Bot, self).save(*args, **kwargs)
{% for members in bot.team_members.all %}}
I ended up changing the model, but I also realized I was doing {{ bot.name }} instead of {{ members.name }} to get the developers name in template, so I doing it wrong.
Related
I have a model Log and another model Solutions and I am using DetailView to display details of each log
Each log can have many solutions.
There is a log field in the Solutions model that is Foreign Key to Log model..
Now how do I access both Log model and Solutions of that particular log in the same html template if I want to display all the solutions of that particular log below the details of the log
models.py:
class Log(models.Model):
title = models.CharField(blank=False, max_length=500)
content = models.TextField(blank=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=50, null=False, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE,null=True, blank=True)
image = models.ImageField(
upload_to='images', blank=True)
def save(self, *args, **kwargs):
super().save()
self.slug = self.slug or slugify(self.title + '-' + str(self.id))
super().save(*args, **kwargs)
class Meta:
verbose_name = ("Log")
verbose_name_plural = ("Logs")
def __str__(self):
return f"{self.title}"
def get_absolute_url(self):
return reverse("log-detail", kwargs={"question": self.slug})
class Solutions(models.Model):
log = models.ForeignKey(
Log, on_delete=models.CASCADE, blank=True, null=True)
author = models.ForeignKey(User, on_delete=models.CASCADE,null=True, blank=True)
solution = models.TextField(null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=50, null=False, blank=True)
image = models.ImageField(
upload_to='images', blank=True)
def save(self, *args, **kwargs):
self.slug = self.slug or slugify(self.solution)
super().save(*args, **kwargs)
class Meta:
verbose_name = ("Solution")
verbose_name_plural = ("Solutions")
def __str__(self):
return f" {self.solution} "
views.py:
class LogDetailView(DetailView):
model = Log
slug_url_kwarg = 'question'
slug_field = 'slug'
log_detail.html:
{% extends 'log/base.html' %}
{%load crispy_forms_tags %}
{% block content %}
<title>Error Logger - {{object.title}}</title>
<div class="main container mt-4 p-3 mb-4">
<img style='display:inline;' class='rounded-circle account-img' src="{{ object.author.profile.avatar.url }}" alt="">
<h1 style='display:inline;'>
{{ object.title }}
</h1>
<p>Author: {{ object.author }}</p>
<p>Date and time of creation: {{ object.created }}</p>
<span> Details </span>:
<p class="big ml-4">{{ object.content }} <br />
{% if object.image %}
<img style="width: 20vw" class="mt-4" src="{{ object.image.url }}" alt="image" />
{% else %}
{% endif %}
</p>
</div>
<br />
<a
class="btn btn-outline btn-info button-solution"
href="#"
>Add solution</a
>
You can enumerate over these in the template by accessing the relation in reverse, this is normally modelname_set, unless you set a related_name=…. So in this case it is solutions_set:
{% for solution in object.solutions_set.all %}
{{ solution }}
{% endfor %}
If the ForeignKey has a related_name=… [Django-doc], for example with:
class Solutions(models.Model):
log = models.ForeignKey(
Log,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='solutions'
)
# …
Then we access this with:
{% for solution in object.solutions.all %}
{{ solution }}
{% endfor %}
Note: normally a Django model is given a singular name, so Solution instead of Solutions.
This allows me to slice
#models.py
Class Home(models.Model):
house_name = models.CharField(max_length=20, blank=False, null=True)
location = models.CharField(max_length=20, blank=False, null=True)
rooms = models.CharField(max_length=20, blank=False, null=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.house_name)
super(Home, self).save(*args, **kwargs)
#views.py
def homes(request):
home_model = Home.objects.filter(admin_approval=True)
return render(request, 'home/home.html', {'home_model': home_model})
#home.html
<div class="container">
<div class="row row-cols-lg-4 row-cols-md-3 text-center text-light">
{% for home in home_model|slice:":10" %}
<div class="row-inside-content">
<img src="#">
<p>{{ home.home_name|title }}</p>
</div>
{% endfor %}
</div>
Meanwhile if I was to use the same views, and same model and also try to render homes in another page like home/house.html, nothing gets render. I'm utterly confused as to why this is happening.
i am trying to show data from multiple models in one single view and one single template and i succeed with that but i have problem , the problem is posts from android model keep show at first because i have added android first in html page but what i want to do is show posts by date published what should i do
models.py :
class android(models.Model):
name = models.CharField(max_length=50,default="")
slug = models.SlugField(max_length=250,default="")
post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
def get_image(self):
if self.app_image and hasattr(self.app_image, 'url'):
return self.app_image.url
else:
return '/path/to/default/image'
def __str__(self):
return self.name
class Meta:
ordering = ('-post_date',)
class PCgames(models.Model):
name = models.CharField(max_length=50,default="")
slug = models.SlugField(max_length=250,default="")
post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
def get_image(self):
if self.app_image and hasattr(self.app_image, 'url'):
return self.app_image.url
else:
return '/path/to/default/image'
def __str__(self):
return self.name
class Meta:
ordering = ('-post_date',)
views.py :
def home_page(request):
pcgamesforhome = PCgames.objects.all()
androidforhome = Android.objects.all()
context = {'pcgamesforhome' : pcgamesforhome,'androidforhome' : androidforhome}
return render(request,'html_file/home.html',context=context)
home.html :
<div class="container">
<div class='row'>
{% for android in androidforhome %}
<div class='col-xs-12 col-sm-6 col-md-4 website-thumb'>
<a href="{{ android.slug }}">
<img src="{{ android.get_image }}" class='image_control_for_home_page_pc_games' alt=''> </a>
<h3>{{ android.name }}</h3> </div>
{% endfor %}
</div>
<div class="container">
<div class='row'>
{% for home_page in pcgamesforhome %}
<div class='col-xs-12 col-sm-6 col-md-4 website-thumb'>
<a href="{{ home_page.slug }}">
<img src="{{ home_page.get_image }}" class='image_control_for_home_page_pc_games' alt=''> </a>
<h3>{{ home_page.name }}</h3> </div>
{% endfor %}
</div>
so now what should i do to show posts from all models order by date ?
your database structure is wrong. instead of having two model for android and PC, you can have one model and a field specifying object type with choices
class Foo(models.Model):
Type = (
('android', 'android'),
('pc', 'pc'),
)
name = models.CharField(max_length=50,default="")
slug = models.SlugField(max_length=250,default="")
post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
type = models.CharField(max_length=10, choices=Type)
if you like to have a special field for each android or pc, you can create fields with blank and null true attr.
views.py:
# get all of them and order them by creation date
Foo.obejcts.all().order_by('-post_date')
# get android type objects
Foo.objects.filter(type='android')
# get pc type objects
Foo.objects.filter(type='pc')
a basic example would be
class Category(models.Model):
name = models.CharField(max_length=30)
slug = models.SlugField(max_length=50)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(blank=True)
post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
slug = models.SlugField(max_length=50)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Meta:
#recent post in top
ordering = ['-post_date']
in views to filter based on category:
pc_games = Post.objects.select_related("category_set").filter(category__name='pc_games')
android = Post.objects.select_related("category_set").filter(category__name='android')
I'm trying to get my three models working correctly on one DetailView. I have all of them loaded, but the model that contains the images keeps showing the first image. I know I need to filter it somehow, but I don't really know how to do it. Since I need the product info to filter the images. Here is my code:
views:
class VendorDetailView(DetailView):
context_object_name = 'vendor_detail'
model = Vendor
queryset = Vendor.objects.all()
template_name = 'vendor_details.html'
def get_context_data(self, **kwargs):
context = super(VendorDetailView, self).get_context_data(**kwargs)
context['products'] = Product.objects.filter(vendor=self.get_object())
context['image'] = ProductImage.objects.all()
return context
models:
class Product(models.Model):
product_model = models.CharField(max_length=100)
vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
slug = models.SlugField(max_length=200, unique=True, null=True)
length = models.CharField(max_length=50)
length_range = models.ForeignKey(LengthRange, on_delete=models.SET_NULL, null=True, blank=True)
hull_type = models.ForeignKey(Hull, on_delete=models.SET_NULL, null=True, blank=True)
max_beam = models.CharField(max_length=50, blank=True, default='0')
cockpit_length = models.CharField(max_length=50, blank=True, default='0')
cockpit_beam = models.CharField(max_length=50, blank=True, default='0')
price = models.DecimalField(decimal_places=2, max_digits=50)
power = models.ForeignKey(PowerConfiguration, on_delete=models.SET_NULL, null=True, blank=True)
average_bare_hull_weight = models.CharField(max_length=50, blank=True, default='0')
fuel_capacity = models.CharField(max_length=50, blank=True, default='0')
seating_capacity = models.ForeignKey(Seat, on_delete=models.SET_NULL, null=True, blank=True)
speed = models.ForeignKey(SpeedRange, on_delete=models.SET_NULL, null=True, blank=True)
warranty = models.CharField(max_length=256, default='None')
hull_only_available = models.BooleanField(blank=False, default=False)
description = models.TextField()
featured = models.BooleanField(blank=False, default=False)
class Meta:
ordering = ['product_model']
def __str__(self):
return '{} {}'.format(self.vendor, self.product_model)
def save(self, *args, **kwargs):
# just check if product_model or vendor.name has changed
self.slug = '-'.join((slugify(self.vendor.name), slugify(self.product_model)))
super(Product, self).save(*args, **kwargs)
class ProductImage(models.Model):
product = models.ForeignKey(Product, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='product_images', blank='img/92-thumb.jpg')
class Vendor(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(max_length=200, unique=True, null=True)
website = models.CharField(max_length=256)
vendor_email = models.CharField(max_length=100)
images = models.ImageField(upload_to='vendor_images', blank='img/92-thumb.jpg')
description = models.TextField()
def __str__(self):
return self.name
def save(self, *args, **kwargs):
# just check if product_model or vendor.name has changed
self.slug = slugify(self.name)
super(Vendor, self).save(*args, **kwargs)
Template:
<div class="preview col-md-4">
<div class="vendor-pic">
{% if vendor_detail.images %}
<div class="tab-pane">
<img class="vendor-preview" src="{{ vendor_detail.images.url }}"/></div>
{% endif %}
</div>
**[snipped for brevity]**
</div>
<div class="details col-md-6">
<h3 class="vendor-title">{{ vendor_detail.name }} Boats</h3>
<p class="vendor-description">{{ vendor_detail.description | linebreaksbr }}</p>
<h5 class="website">website: <span>{{ vendor_detail.website }}</span></h5>
</div>
</div>
{% for product in products %}
<div class="product-card">
<div class="product">
<div class="top">{% for product_image in image.all %}
{% if product_image.image %}
<img class="product-img" src="{{ product_image.image.url }}">
{% endif %}
{% endfor %}
</div>
<div class="bottom">
<div class="left">
<div class="details">
<h3>{{ product.vendor }} {{ product.product_model }}</h3>
<p>Starting at ${{ product.price|intcomma }}</p>
</div>
<div class="buy"><a
href="{% url 'boatsales:product_detail' product.slug %}"><i
class="material-icons">pageview</i></a></div>
</div>
</div>
</div>
<div class="inside">
<div class="icon"><i class="material-icons">info_outline</i></div>
<div class="contents">
<p style="text-align: justify">{{ product.description|linebreaksbr }}</p>
</div>
</div>
</div>
{% endfor %}
I've tried multiple ways to filter the product images, but the only thing I can get working is the ProductImages.objects.all() which of course is incorrect. Any help you can provide would be greatly appreciated. Thanks in advance.
You don't need a queryset for the images, you can access them through the Product instances using the related_name like this:
{% for product in products %}
<div class="product-card">
<div class="product">
<div class="top">
{% for product_image in product.images.all %}
<img class="product-img" src="{{ product_image.image.url }}">
{% endfor %}
</div>
...
</div>
{% endfor %}
This may be a simple answer but after days of searching I cannot seem to figure out the correct way to achieve this.
I have a template where I want to show all the questions that are related to an assessment that has been assigned to a user. I thought that I could use the results from:
ResponseDetails = AssessmentResponse.objects.prefetch_related('assessment').filter(id=response_id)
by looking into the object and grabbing the assessment_id which I could then pass into the next query-set as a filter but I couldn't get that to work.
Problem: Because the view doesn't filter based on the assessment_id found in the AssessmentResponse model, it gives me every question in the AssessmentQuestion model.
An answer would allow me to actually have a good nights sleep trying to figure it out.
Views
def UpdateAssessmentResponse(request, response_id):
ResponseDetails = AssessmentResponse.objects.prefetch_related('assessment').filter(id=response_id)
QuestionList = AssessmentQuestion.objects.all()
ChoiceList = AssessmentQuestionChoice.objects.all()
context = {
"ResponseDetails":ResponseDetails,
"QuestionList":QuestionList,
"ChoiceList": ChoiceList,
#"ID" : ID,
}
return render(request, "assessment/assessment_response_update.html", context)
Template
{% if QuestionList and ResponseDetails%}
{% csrf_token %}
{% for question in QuestionList %}
<p> {{ question.question_text }} </p>
{% for choice in ChoiceList %}
{% if choice.question_id == question.pk %}
<fieldset id="group1">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label class="custom-control-label" for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
</div>
<fieldset id="group1">
{% endif %}
{% endfor %}
{% endfor %}
<div class="card-footer">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
{% else %}
<p>There are currently no questions for this assessment.</p>
{% endif %}
Models:
class AssessmentForm(models.Model):
name = models.CharField(max_length=400)
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
is_published = models.BooleanField()
due_date = models.DateField(default=datetime.now, blank=True, null=True)
def __str__(self):
return self.name
class AssessmentResponse(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
assessment = models.ForeignKey('AssessmentForm', on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
last_update = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse('assessment_response_detail', args=[str(self.id)])
#def get_assessment_id(self):
# return self.assessment
def __str__(self):
return self.user
class AssessmentQuestionType(models.Model):
type = models.CharField(max_length=30)
def __str__(self):
return self.type
class AssessmentQuestionCategory(models.Model):
name = models.CharField(max_length=200)
assessment = models.ForeignKey('AssessmentForm', on_delete=models.CASCADE)
def __str__(self):
return self.name
class AssessmentQuestionSubCategory(models.Model):
name = models.CharField(max_length=200)
parent_category = models.ForeignKey('AssessmentQuestionCategory', on_delete=models.CASCADE)
def __str__(self):
return self.name
#CHOICES_HELP_TEXT = _(u"""The choices field is only used if the question type if the question type is 'radio', 'select', or 'select multiple' provide a comma-separated list of options for this question .""")
class AssessmentQuestion(models.Model):
question_type = models.ForeignKey('AssessmentQuestionType', on_delete=models.PROTECT)
question_text = models.TextField()
is_required = models.BooleanField()
category = models.ForeignKey('AssessmentQuestionCategory', on_delete=models.PROTECT, blank=True, null=True)
subcategory = models.ForeignKey('AssessmentQuestionSubCategory', on_delete=models.PROTECT, blank=True, null=True)
assessment = models.ForeignKey('AssessmentForm', on_delete=models.CASCADE)
def __str__(self):
return self.question_text
class AssessmentQuestionChoice(models.Model):
question = models.ForeignKey(AssessmentQuestion, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200, blank=True, null=True)
def __str__(self):
return self.choice_text
class AssessmentAnswer(models.Model):
text = models.CharField(max_length=1024)
question = models.ForeignKey('AssessmentQuestion', on_delete=models.CASCADE)
response = models.ForeignKey('AssessmentResponse', on_delete=models.PROTECT)
def __str__(self):
return self.text
Figured it out! Objects.filter is a lazy query so it wasn't actually available to my other query-set to use as a filter. Solved it by using objects.get instead.