I have a boolean field for whether or not an item is active:
is_active = models.BooleanField(default=True)
It seems pretty straightforward, my template will display items that are active:
{% for p in products|dictsortreversed:"id" %}
{% if p.is_active %}
<a href="{{ p.get_absolute_url }}">
{{ p.name }}
</a>
{% endif %}
For some reason all items are returned even if the field is 0 in the database. When I uncheck the boolean field in the django admin, it updates correctly to 0 in the database, but still shows as being checked in the admin...
It seems like django is reading the field as True, regardless of the boolean value.
Model
class Product(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=255, unique=True, help_text='Unique value for product page URL, created from name')
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
old_price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
image = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
quantity = models.IntegerField()
description = models.TextField()
meta_keywords = models.CharField('Meta Keywords', max_length=255, help_text='Comma-delimited set of SEO keywords for meta tag')
meta_description = models.CharField('Meta Description', max_length=255, help_text='Content for description meta tag')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
categories = models.ForeignKey(Category, null=True)
publish_date = models.DateField(blank=True, null=True)
issue_one = models.CharField(blank=True, null=True, max_length=255)
issue_two = models.CharField(blank=True, null=True, max_length=255)
issue_three = models.CharField(blank=True, null=True, max_length=255)
class Meta:
db_table = 'products'
ordering = ['-created_at']
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_product', (), {'product_slug': self.slug})
View:
def index(request, template_name="catalog/index.html"):
""" site home page """
page_title = 'Visible Language Ordering'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
Related
I have a product update form where I want to update the sizes of a product, with a many-to-many column relation.
I am able to get the saved values but I can't get item ID or size.
{{item.id}} shows empty value.
{% for item in form.size.value %}
<span>
<input type="checkbox" name="size" id="{{ item.id }}" value="{{ item.id }}">
<label for="{{ item.id }}">{{ item }}</label>
</span>
{% endfor %}
SIZE MODEL
class Size(models.Model):
identifier = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
size = models.CharField(max_length=200, unique=True, null=False, blank=False)
active = models.BooleanField(default=True)
date_created = models.TimeField(verbose_name='Date Created', auto_now_add=True)
date_updated = models.DateTimeField(verbose_name='Last Updated', auto_now=True)
PRODUCT MODEL
class Product(models.Model):
identifier = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
name = models.CharField(max_length=200, null=False, blank=False)
slug = models.SlugField(max_length=30, unique=True)
showcased = models.BooleanField(default=False)
recommended = models.BooleanField(default=False)
active = models.BooleanField(default=True)
price = models.DecimalField(max_digits = 5, decimal_places = 2, null=True, blank=True)
pagetitle = models.CharField(max_length=200, null=True, blank=True)
shortDescription = models.CharField(max_length=200, null=True, blank=True)
longDescription = HTMLField(null=True, blank=True)
specifications = models.TextField(null=True, blank=True)
features = models.TextField(null=True, blank=True)
care = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
subCategory = models.ForeignKey(SubCategory, null=True, blank=True, on_delete=models.PROTECT)
image = models.ManyToManyField(Image, blank=True)
size = models.ManyToManyField(Size, blank=True)
tag = models.ManyToManyField(Tag, blank=True)
date_created = models.TimeField(verbose_name='Date Created', auto_now_add=True)
date_updated = models.DateTimeField(verbose_name='Last Updated', auto_now=True)
I have tried different ways but not had success in getting the name or id
def updateProduct(request, pk):
categories = Category.objects.all()
sizes = Size.objects.all()
tags = Tag.objects.all()
product = Product.objects.get(id=pk)
subCategories = SubCategory.objects.filter(category=product.category.id)
images = product.image.all()
if request.method == 'POST':
form = ProductForm(request.POST, instance=product)
if form.is_valid():
form.save()
return redirect('product-panel')
form = ProductForm(instance=product)
return render(request, 'public/views/backend/product-update.html', {'categories':categories,'subCategories':subCategories, 'sizes':sizes, 'tags':tags, 'form':form, 'images':images})
I have got 2 models. Asset and Asset_Type. In my asset_type detail view i would like to list all assets of that asset type. I think I have to use models.Asset.queryset().filter() but i can't get it to work.
On my template I would like to loop though the list with a 'for' (example: object in list) and print the values like this {{ object.name }}
models.py
class Asset(models.Model):
# Relationships
room = models.ForeignKey("asset_app.Room", on_delete=models.SET_NULL, blank=True, null=True)
model_hardware = models.ForeignKey("asset_app.Model_hardware", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=30)
serial = models.CharField(max_length=30, unique=True, blank=True, null=True, default=None)
mac_address = models.CharField(max_length=30, null=True, blank=True)
purchased_date = models.DateField(null=True, blank=True)
may_be_loaned = models.BooleanField(default=False, blank=True, null=True)
notes = models.TextField(max_length=448, null=True, blank=True)
ip = models.CharField(max_length=90, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Meta:
ordering = ["name"]
def __str__(self):
return str(self.name)
def get_absolute_url(self):
return reverse("asset_app_asset_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_asset_update", args=(self.pk,))
class Asset_type(models.Model):
# Fields
name = models.CharField(max_length=30)
last_updated = models.DateTimeField(auto_now=True, editable=False)
created = models.DateTimeField(auto_now_add=True, editable=False)
notes = models.TextField(max_length=448, null=True, blank=True)
class Meta:
ordering = ["name"]
def __str__(self):
return str(self.name)
def get_absolute_url(self):
return reverse("asset_app_asset_type_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_asset_type_update", args=(self.pk,))
class Model_hardware(models.Model):
# Relationships
asset_type = models.ForeignKey("asset_app.Asset_type", on_delete=models.SET_NULL, blank=True, null=True)
brand = models.ForeignKey("asset_app.Brand", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=30)
notes = models.TextField(max_length=448, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Meta:
ordering = ["name"]
def __str__(self):
return str(self.name) + " :: " + str(self.brand.name) + " :: " + self.asset_type.name
def get_absolute_url(self):
return reverse("asset_app_model_hardware_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_model_hardware_update", args=(self.pk,))
views.py
class Asset_typeDetailView(generic.DetailView):
model = models.Asset_type
form_class = forms.Asset_typeForm
You can simply iterate over the related objects in the template by using the default related name which is the model name in lowercase with _set appended. So asset_type.model_hardware_set.all() will give you all Model_hardware instances related to Asset_type and similarly for model_hardware.asset_set.all():
{% for model_hardware object.model_hardware_set.all %}
{% for asset in model_hardware.asset_set.all %}
{{ asset.name }}
{% endfor %}
{% endfor %}
But this can become slow, since we run into the N + 1 problem that is for each model hardware we will be making queries to get it's assets. We can use prefetch_related_objects on your model instance to prefetch all the related objects (in fewer queries) this and make it faster:
from django.db.models import prefetch_related_objects
from django.views.generic import DetailView
class YourDetailView(DetailView):
model = Asset_type
template_name = '<your_template_name>.html'
def get_object(self, queryset=None):
obj = super().get_object(queryset=queryset)
prefetch_related_objects([obj], 'model_hardware__asset')
return obj
Note: Class names in python should ideally be in PascalCase not Some_case (Don't think there is any such convention as you make
here), hence ModelHardware instead of Model_hardware and
AssetType instead of Asset_type would be better names.
I need to display some product's supplier, next to {{product.description}} but I can't get it to show on my table.
models.py
class Supplier(models.Model):
name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
sku = models.IntegerField(null=True)
description = models.CharField(max_length=30)
costprice = models.FloatField(null=True, max_length=99, blank=True)
retailprice = models.FloatField(null=True, max_length=99, blank=True)
barcode = models.CharField(null=True, max_length=99, unique=True)
image = models.ImageField(null=True, blank=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.description
views.py
def products(request):
products = Product.objects.all()
suppliers = Supplier.objects.all()
context = {'products': products,
'suppliers': suppliers}
return render(request, 'crmapp/products.html', context)
products.html
<tr>
{% for product in products %}
<td>{{product.id}}</td>
<td><h6><strong>{{product.description}}</strong></h6></td>
<td >{{products.supplier}}</td>
<td>£{{product.costprice |floatformat:2}}</td>
<td>£{{product.retailprice |floatformat:2}}</td>
<td>{{product.barcode}}</td>
</tr>
{% endfor %}
Spelling mistake, I think.
<td >{{products.supplier}}</td>
Must be:
<td >{{product.supplier}}</td>
Notice I've removed the s in products.
Also, you don't need this in your views.py:
suppliers = Supplier.objects.all()
{{product.supplier}} will trigger a query to the db. To avoid that, use prefetch_related.
products = Product.objects.all().prefetch_related('supplier')
Note that this is optional. It will just improve efficency, but merely fixing the spelling mistake answers your question.
I'm trying to add extra content to Djangos Class-based view to the template
I have some models like this
class District(models.Model):
district = models.CharField(max_length=255, null=False, unique=False, blank=True)
def __str__(self):
return self.district
class Street(models.Model):
street_name = models.CharField(max_length=255, null=False, unique=False, blank=True)
district = models.ForeignKey(District, verbose_name=_('district'), on_delete=models.CASCADE, null=True, blank=True)
zone = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.street_name
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name="author", on_delete=models.SET_NULL)
timestamp = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=1, choices=STATUS, default=CREATED)
comment = models.CharField(max_length=255, null=True, unique=False, blank=True)
name = models.CharField(max_length=255, null=True, unique=False)
street = models.ForeignKey(Street, verbose_name=_('street'), on_delete=models.CASCADE, null=True, blank=True)
class ArticlesListView(LoginRequiredMixin, PermissionRequiredMixin,ListView):
model = Article
paginate_by = 50
context_object_name = "articles"
permission_required = 'is_staff'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['Filter_name'] = Article.objects.order_by().values('name').distinct()
context['Filter_user'] = Article.objects.order_by().values('user').distinct()
return context
def get_queryset(self, **kwargs):
return Article.objects.all()
And late in the template
{% for f in Filter_name %}
<ul>
<li>{{f.name}}</li>
</ul>
{% endfor %}
How can I display a list of the district names and a list of the author names in the template with ForeignKey?
U can try something like that
{% for item in model_1.foreign_model_set.all %}
<h1>{{ item }}</h1>
{% endfor %}
I am trying to get my html form to allow me to pass the company model instance. As of now, I can pull the names of each company instance, however, what would I put into the value attibute of the option field to have it select the instance correctly?
<option value="what to put here?">{{Company.name}}</option>
I was hoping to do this through HTML forms and not Django forms as I have used AJAX to make a nice little live-updating interface.
models.py
class Company(models.Model):
name = models.CharField(max_length=30, null=True, blank=True)
email = models.CharField(max_length=40, null=True, blank=True)
phone = models.CharField(max_length=15, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
notes = models.CharField(max_length=400, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, blank=True)
updated = models.DateTimeField(auto_now=True, blank=True)
class Meta:
ordering = ["name"]
def __str__(self):
return self.name
class Contact(models.Model):
firstname = models.CharField(max_length=20, null=True, blank=True)
lastname = models.CharField(max_length=20, null=True, blank=True)
email = models.CharField(max_length=40, null=True, blank=True)
phone = models.CharField(max_length=15, null=True, blank=True)
title = models.CharField(max_length=20, null=True, blank=True)
notes = models.CharField(max_length=400, null=True, blank=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ["lastname"]
def __str__(self):
return self.firstname
views.py
class contact_manager(ListView):
template_name = 'crm/contact_manager.html'
context_object_name = 'contact_manager'
queryset = Contact.objects.all()
def get_context_data(self, **kwargs):
context = super(contact_manager, self).get_context_data(**kwargs)
context['contact'] = Contact.objects.all()
context['company_list'] = Company.objects.all()
# And so on for more models
return context
contact_manager.html
<div class="form-group">
<select class="form-control" name="company" placeholder="Company">
<option value="">Please select a company</option>
{% for Company in company_list %}
<option value="{{Company.name}}">{{Company.name}}</option>
{% endfor %}
</select>
</div>
If you are looking for a unqiue identifier for each option, that links to a model instance on the backend, that is what the ID field is for (Company.id):
<option value="{{ Company.id }}">{{Company.name}}</option>
Then on the backend you can retrieve the model with the posted id:
Company.get(id=posted_id)
Note: id is by default added to your model as the primary key and is a auto incrememting integer.