Please forgive me if this has already been asked
I am following a course online, albeit 3 years old, so somethings have been updated since then
However datetime seems to be roughly the same from what I can see.
The problem arises when we use timedelta to filter all the sales in the last month
I have added some test sales over the weeks and when I tried to filter it down to the last 48 hours, nothing
with a bit of testing i went back 12 days (as of this question and a list of items sold back on the 20th February showed up but nothing sooner.
I went into the admin and updated one of them and refreshed the page. and it disappeared completely
Can anyone provide any insight as to what i am missing?
If you need more information please say:
Models.py
from decimal import Decimal
import datetime
from django.conf import settings
from django.db import models
from django.db.models import Count, Sum, Avg
from django.db.models.signals import pre_save, post_save
from django.urls import reverse
from django.utils import timezone
from addresses.models import Address
from billing.models import BillingProfile
from carts.models import Cart
from ecommerce.utils import unique_order_id_generator
from products.models import Product
ORDER_STATUS_CHOICES = (
('created', 'Created'),
('paid', 'Paid'),
('shipped', 'Shipped'),
('refunded', 'Refunded'),
)
class OrderManagerQuerySet(models.query.QuerySet):
def recent(self):
return self.order_by("-updated", "-timestamp")
def by_date(self):
now = timezone.now() - datetime.timedelta(days=12)
return self.filter(updated__day__gte=now.day)
def totals_data(self):
return self.aggregate(Sum("total"), Avg("total"))
def cart_data(self):
return self.aggregate(Sum("cart__products__price"), Avg("cart__products__price"), Count("cart__products"))
def by_status(self, status="shipped"):
return self.filter(status=status)
def not_refunded(self):
return self.exclude(status='refunded')
def by_request(self, request):
billing_profile, created = BillingProfile.objects.new_or_get(request)
return self.filter(billing_profile=billing_profile,)
def not_created(self):
return self.exclude(status='created')
class OrderManager(models.Manager):
def get_queryset(self):
return OrderManagerQuerySet(self.model, using=self._db)
def by_request(self, request):
return self.get_queryset().by_request(request)
def new_or_get(self, billing_profile, cart_obj):
created = False
qs = self.get_queryset().filter(
billing_profile=billing_profile,
cart=cart_obj,
active=True,
status='created'
)
if qs.count() == 1:
obj = qs.first()
else:
obj = self.model.objects.create(
billing_profile=billing_profile,
cart=cart_obj
)
created = True
return obj, created
class Order(models.Model):
billing_profile = models.ForeignKey(BillingProfile, null=True, blank=True, on_delete=models.CASCADE)
order_id = models.CharField(max_length=120, blank=True)
shipping_address = models.ForeignKey(Address, related_name="shipping_address", null=True, blank=True, on_delete=models.CASCADE)
billing_address = models.ForeignKey(Address, related_name="billing_address", null=True, blank=True, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
status = models.CharField(max_length=120, default='created', choices=ORDER_STATUS_CHOICES)
shipping_total = models.DecimalField(default=5.99, max_digits=100, decimal_places=2)
total = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
active = models.BooleanField(default=True)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.order_id
objects = OrderManager()
class Meta:
ordering = ['-timestamp', '-updated']
def get_absolute_url(self):
return reverse("orders:detail", kwargs={'order_id': self.order_id})
def get_status(self):
if self.status == "refunded":
return "Refunded order"
elif self.status == "shipped":
return "Shipped"
return "Shipping Soon"
def update_total(self):
cart_total = self.cart.total
shipping_total = self.shipping_total
new_total = Decimal(cart_total)+Decimal(shipping_total)
formatted_total = format(new_total, '.2f')
print(type(new_total))
self.total = formatted_total
self.save()
return new_total
def check_done(self):
shipping_address_required = not self.cart.is_digital
shipping_done = False
if shipping_address_required and self.shipping_address:
shipping_done = True
elif shipping_address_required and not self.shipping_address:
shipping_done = False
else:
shipping_done = True
billing_profile = self.billing_profile
billing_address = self.billing_address
total = self.total
if billing_profile and shipping_done and billing_address and total > 0:
return True
return False
def update_purchases(self):
for p in self.cart.products.all():
obj, create = ProductPurchase.objects.get_or_create(
order_id = self.order_id,
product = p,
billing_profile= self.billing_profile,
)
return ProductPurchase.objects.filter(order_id = self.order_id).count()
def mark_paid(self):
if self.status != 'paid':
if self.check_done():
self.status = "paid"
self.save()
self.update_purchases()
return self.status
def pre_save_create_order_id(sender, instance, *args, **kwargs):
if not instance.order_id:
instance.order_id = unique_order_id_generator(instance)
qs= Order.objects.filter(cart=instance.cart).exclude(billing_profile=instance.billing_profile)
if qs.exists():
qs.update(active=False)
pre_save.connect(pre_save_create_order_id, sender=Order)
def post_save_cart_total(sender, instance, created, *args, **kwargs):
if not created:
cart_obj = instance
cart_total = cart_obj.total
cart_id = cart_obj.id
qs = Order.objects.filter(cart__id=cart_id)
if qs.count() ==1:
order_obj = qs.first()
order_obj.update_total()
post_save.connect(post_save_cart_total,sender=Cart)
def post_save_order(sender, instance, created, *args, **kwargs):
print("running")
if created:
print("updating...first")
instance.update_total()
post_save.connect(post_save_order,sender=Order)
class ProductPurchaseQuerySet(models.query.QuerySet):
def active(self):
return self.filter(refunded=False)
def digital(self):
return self.filter(product__is_digital=True)
def by_request(self, request):
billing_profile, created = BillingProfile.objects.new_or_get(request)
return self.filter(billing_profile=billing_profile,)
class ProductPurchaseManager(models.Manager):
def get_queryset(self):
return ProductPurchaseQuerySet(self.model, using=self._db)
def all(self):
return self.get_queryset().active()
def digital(self):
return self.get_queryset().active().digital()
def by_request(self, request):
return self.get_queryset().by_request(request)
def products_by_id(self, request):
qs = self.by_request(request).digital()
ids_ = [x.product.id for x in qs]
return ids_
def products_by_request(self, request):
ids_ = self.products_by_id(request)
product_qs = Product.objects.filter(id__in=ids_).distinct()
return product_qs
class ProductPurchase(models.Model):
order_id = models.CharField(max_length=120)
billing_profile = models.ForeignKey(BillingProfile, on_delete=models.CASCADE) # billingprofile.productpurchase_set.all()
product = models.ForeignKey(Product, on_delete=models.CASCADE) # product.productpurchase_set.count()
refunded = models.BooleanField(default=False)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
objects = ProductPurchaseManager()
def __str__(self):
return self.product.title
Views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count, Sum, Avg
from django.http import HttpResponse
from django.views.generic import TemplateView
from django.shortcuts import render
from orders.models import Order
class SalesView(LoginRequiredMixin, TemplateView):
template_name = 'analytics/sales.html'
def dispatch(self, *args, **kwargs):
user = self.request.user
if not user.is_staff:
return render(self.request, "401.html", {})
return super(SalesView, self).dispatch(*args, **kwargs)
def get_context_data(self, *args, **kwargs):
context = super(SalesView, self).get_context_data(*args, **kwargs)
qs = Order.objects.all().by_date()
context['orders'] = qs
context['recent_orders'] = qs.recent().not_refunded()
context['recent_orders_data'] = context['recent_orders'].totals_data()
context['recent_orders_cart_data'] = context['recent_orders'].cart_data()
context['shipped_orders'] = qs.recent().not_refunded().by_status("shipped")
context['shipped_orders_data'] = context['shipped_orders'].totals_data()
context['paid_orders'] = qs.recent().not_refunded().by_status("paid")
context['paid_orders_total'] = context['paid_orders'].totals_data()
return context
Sales.html
{% extends "base.html" %}
{% block content%}
<div class="row">
<div class="col-12">
<h1>Sales Data</h1>
</div>
</div>
<div class="row">
<div class="col">
<p>Recent Toal: £{% if recent_orders_data.total__sum %} {{ recent_orders_data.total__sum }}{% else %}0 {% endif %}</p>
<ol>
{% for order in recent_orders %}
<li>{{ order.order_id}}
{{ order.total}}
{{ order.updated}} </li>
{% endfor %}
</ol>
</div>
<div class="col">
<p>Shipped Total: £{% if shipped_orders_data.total__sum %}{{ shipped_orders_data.total__sum }}{% else %}0{% endif %}</p>
<ol>
{% for order in shipped_orders %}
<li>{{ order.order_id}}
{{ order.total}}
{{ order.updated}}</li>
{% endfor %}
</ol>
</div>
<div class="col">
<p>Paid Totals: £{% if shipped_orders_data.total__sum %}{{ paid_orders_total.total__sum }}{% else %}0{% endif %}</p>
<ol>
{% for order in paid_orders %}
<li>{{ order.order_id}}
{{ order.total}}
{{ order.updated}}</li>
{% endfor %}
</ol>
</div>
</div>
{% endblock %}
In your filter by_date method you are using a filter on the day not the date. This won't help as it'll return the day of the month. So if the date was 2020-03-11 it would return 29 for now.day. If you change .day for .date() as well as updated__day__gte for updated__date__gte it should be okay
def by_date(self):
now = timezone.now() - datetime.timedelta(days=12)
return self.filter(updated__date__gte=now.date())
The following should work fine:
now = timezone.now().date() - datetime.timedelta(days=12)
return self.filter(updated__date__gte=now)
Related
I have two models: a Project model and ProjectNotes. ProjectNotes are notes that are related to Projects. The ProjectNotes model has a project field that is a foreign key of the related Project.
The problem I have is that when I delete a note on a project, the entire project is deleted. Only the note should be deleted. I think I have on_delete=models.cascade set up correctly on the ProjectNotes model. So I think the issue is with the view.
The models:
class ProjectManager(models.Manager):
def search(self, query=None):
qs = self.get_queryset()
if query is not None:
or_lookup = (
Q(title__icontains=query) |
Q(description__icontains=query)
# Q(slug__icontains=query)
)
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
return qs
def get_with_counted_notes_documents_todos(self):
queryset = self.get_queryset().annotate(
num_notes=Count('notes'),
num_documents=Count('project_documents'),
num_todos=Count('todo_group')
)
return queryset
class Project(models.Model):
title = models.CharField(max_length= 200)
description = tinymce_models.HTMLField()
status = models.CharField(max_length=20, choices=PROJECT_CHOICES, default="active")
date = models.DateTimeField(auto_now_add=True, null=True)
created_by = models.ForeignKey(CustomUser, editable=False, null=True, blank=True, on_delete=models.RESTRICT)
tags = tagulous.models.TagField(to=SiteWideTags, blank=True, related_name='projects_tags')
objects = ProjectManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('company_project:project_detail', args=[str(self.id)])
class ProjectNotesManager(models.Manager):
def search(self, query=None):
qs = self.get_queryset()
if query is not None:
or_lookup = (
Q(title__icontains=query) |
Q(body__icontains=query)
# Q(slug__icontains=query)
)
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
return qs
class ProjectNotes(models.Model):
title = models.CharField(max_length=200)
body = tinymce_models.HTMLField()
project = models.ForeignKey(Project, default=0, blank=True, on_delete=models.CASCADE, related_name='notes')
date = models.DateTimeField(auto_now_add=True, null=True)
created_by = models.ForeignKey(CustomUser, editable=False, null=True, blank=True, on_delete=models.RESTRICT)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('company_project:project_note_detail', args=[self.project_id, str(self.id)])
objects = ProjectNotesManager()
The view:
class ProjectNoteDeleteView(DeleteBreadcrumbMixin, DeleteView):
model = ProjectNotes
template_name = 'company_accounts/delete_project_note.html'
#cached_property
def crumbs(self):
project = self.get_object()
relate_notes = self.get_note()
bread_crumbs = [
("projects", reverse(
"company_project:" + CompanyProjects.list_view_name, )
),
(f"{project.title}",
reverse(
"company_project:" + CompanyProjectsDetailView.detail_view_name,
kwargs={'pk': project.id})
),
("notes", reverse(
"company_project:projectnotes_list",
kwargs={'pk': project.id})
),
(f"{relate_notes.title}",
reverse(
"company_project:project_note_detail",
kwargs={'project_pk': project.id, 'pk': self.kwargs.get('pk')})
),
(f"Delete: {relate_notes.title}",
reverse(
"company_project:project_note_detail",
kwargs={'project_pk': project.id, 'pk': self.kwargs.get('pk')})
)
]
return bread_crumbs
def get_object(self):
return get_object_or_404(Project, id=self.kwargs.get('project_pk'))
def get_note(self):
project = self.get_object()
return get_object_or_404(project.notes, id=self.kwargs.get('pk'))
def related_project(self, **kwargs):
project = get_object_or_404(Project, id=self.kwargs.get('project_pk'))
return project
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
context["note"] = self.get_note()
context['project'] = self.get_object()
return context
def get_success_url(self):
return reverse('company_project:project_detail', args=[(self.object.id)])
The URL:
path('project/<int:project_pk>/note/<int:pk>/delete', ProjectNoteDeleteView.as_view(), name='project_note_delete'),
The template:
<!-- templates/company_accounts/delete_project_note.html -->
{% extends 'base.html' %}
{% block content %}
<div class="section-container container">
<div class="general-main-column">
<div class="row">
<form method="post">{% csrf_token %}
<p>Are you sure you want to permanently delete project note "{{ note }}"?</p>
<input type="submit" class="btn btn-danger" value="Confirm">
</form>
</div>
</div>
</div>
{% endblock content %}
Look at the DeleteView implementation here.
As we can see DeleteView calls delete method for the result of calling get_object function, but your implementation of get_object return instance of Project model:
def get_object(self):
return get_object_or_404(Project, id=self.kwargs.get('project_pk'))
so this is a reason why your project deletes after you try to delete project note.
I made a list of events registered today in the inventory template, and I would like to show the total rating of the events(registered today).
I called it from the template by making the sum of the scores a function, but it is not visible. Does anyone know?
views.py
class CalendarView(generic.ListView):
model = Event
template_name = 'cal/calendar.html'
def get_queryset(self, **kwargs):
return Event.objects.all().filter(start_time__date=date.today())
def filter_event_rating_sum(self):
filtered_event = Event.objects.all().filter(start_time__date=date.today())
sum_rating = 0
for each_event in filtered_event:
sum_rating += each_event.rating
return sum_rating
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
d = get_date(self.request.GET.get('month', None))
cal = Calendar(d.year, d.month)
# issue self.request.user
html_cal = cal.formatmonth(self.request.user, withyear=True)
context['calendar'] = mark_safe(html_cal)
context['prev_month'] = prev_month(d)
context['next_month'] = next_month(d)
return context
templates.html
<p class="today">Today</p>
{% for list in object_list %}
<div class="today_list_item">
<span>{{ list.title }}</span>
<span class="each_rating">{{ list.rating }}</span>
</div>
{% endfor %}
<p class="total">TOTAL</p>
{{ sum_rating }}
</div>
models.py
class Event(models.Model):
title = models.CharField(max_length=200)
start_time = models.DateTimeField(default = timezone.now, blank = True)
# default = timezone.now,
profile=models.ForeignKey(Profile, related_name='event',on_delete=models.CASCADE)
rating = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)], blank=True, default='enter your value')
def __str__(self):
return '{}/ {}/ {}'.format(self.id, self.title, self.start_time, self.rating)
you can only use those variables which are in the dictionary returned by get_context_data function. Add this code in get_context_data function like this
queryset['sum_rating'] = self.filter_event_rating_sum()
The main problem for me was: If a user is the owner of the prime then it should return True. But it always returns False.
My models.py:
from django.db import models
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
class Prime(models.Model):
prime_owner = models.ForeignKey(User, null=True)
prime_name = models.CharField(max_length=100)
prime_address = models.CharField(max_length=250)
My views.py:
class PrimeDetails(generic.DetailView):
template_name ='prime/primedetails.html'
model = Prime
def get_context_data(self, **kwargs):
context = super(PrimeDetails, self).get_context_data(**kwargs)
user = self.request.user
prime_owner = Prime.prime_owner
if user == prime_owner:
owner = True
else:
owner = False
context['owner'] = owner
return context
primedetails.html
{% extends 'prime/base.html' %}
{% block content %}
<div class="container">
<h1>{{ owner }}</h1>
<h1>{{object.prime_name }}</h1>
<h3>{{object.prime_address}}</h3>
</div>
{% endblock %}
Prime is a model, not the object.
Try change the Prime to self.get_object(), like this:
def get_context_data(self, **kwargs):
context = super(PrimeDetails, self).get_context_data(**kwargs)
user = self.request.user
prime_owner = self.get_object().prime_owner
if user == prime_owner:
owner = True
else:
owner = False
context['owner'] = owner
return context
I want to show the data of a user which he has entered. This is my model
class IgaiaContent(models.Model):
CONTENT_CHANNELS = (
('YouTube','Youtube'),
('FaceBook','FaceBook'),
('Flickr','Flickr'),
('Instagram','Instagram'),
)
content_name = models.CharField(max_length=255, primary_key=True)
content_type = models.CharField(max_length=255,null=True)
content_source = models.CharField(max_length=255,null=True, choices=CONTENT_CHANNELS)
content_location = models.CharField(max_length=255,null=True)
content_latitude = models.DecimalField(max_digits=20,decimal_places=2,null=True)
content_longitude = models.DecimalField(max_digits=20,decimal_places=2,null=True)
content_embed_code = models.TextField(null=True)
content_description = models.TextField(null=True)
content_tags_user = models.CharField(max_length=255,null=True)
content_time_uploaded = models.DateTimeField(auto_now_add=True)
content_time_updated = models.DateField(null=True)
def __unicode__(self):
return self.content_name
return self.content_type
return self.content_source
return self.content_location
return self.content_latitude
return self.content_longitude
return self.embed_code
return self.description
return self.tags_user
return self.time_uploaded
return self.time_updated
tagging.register(IgaiaContent)
My view
def create_page(request):
if request.method == 'POST':
form = AuthorForm1(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = AuthorForm1()
c = {}
c.update(csrf(request))
return render_to_response('portal/form1.htm',{'form':form},context_instance=RequestContext(request))
My form template:
<form method="post" style="height: 553px; width: 594px">
<div class="style12">
{% csrf_token %}
</br>{{ form.as_p }}
</div>
</form>
thats how i am showing my model values
employee_info1 = {
"queryset" : IgaiaContent.objects.all(),
"template_name" : "portal/emp1.html",
}
urlpatterns = patterns('',
(r'^view5/', list_detail.object_list, employee_info1),
)
emp1.html
{% if object_list %}
<table>
<ul>
{% for item in object_list %}
<li>{{item.content_name}}</li>
<li>{{item.content_type}}</li>
<li>{{item.content_source}}</li>
<li>{{item.content_location}}</li>
<li>{{item.content_latitude}}</li>
<li>{{item.content_longitude}}</li>
<li>{{item.content_embed_code}}</li>
<li>{{item.content_description}}</li>
<li>{{item.content_tags_user}}</li>
<li>{{item.content_time_uploaded}}</li>
<li>{{item.content_time_updated}}</li></ul>
{% empty %}
<td colspan="11">No items.</td>
{% endfor %}
</table>
{% endif %}
It is not displaying specific user value means it is displaying me everything.
can anyone tell me how to show specific user values/data?
You need to update your model so that it contains a field to store the user -
from django.contrib.auth.models import User
class IgaiaContent(models.Model):
#...
user = models.ForeignKey(User)
Then you need to create a ModelForm as described here.
class IgaiaContentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
return super(MyModelForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
kwargs['commit']=False
obj = super(MyModelForm, self).save(*args, **kwargs)
if self.request:
obj.user = self.request.user
obj.save()
class Meta:
model = IgaiaContent
Now update your view so that that you use your new ModelForm
def create_page(request):
if request.method == 'POST':
form = IgaiaContentForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = IgaiaContentForm()
#...
Now in your object_list view you do something like -
from django.shortcuts import render_to_response
def object_list(request):
#....
object_list = IgaiaContent.objects.filter(user=request.user)
return render_to_response('object_list_template.html', {'object_list': object_list})
I'm making a photo app using this light bird tutorial .
The problem is , The pictures that I upload . Won't display on the page.
I have never displayed a picture in django before and I think the problem is with the configuration
My models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from string import join
import os
from PIL import Image as PImage
from mysite.settings import MEDIA_ROOT
class Album(models.Model):
title = models.CharField(max_length=60)
public = models.BooleanField(default=False)
def __unicode__(self):
return self.title
def images(self):
lst = [x.image.name for x in self.image_set.all()]
lst = ["<a href='/media/%s'>%s</a>" % (x, x.split('/')[-1]) for x in lst]
return join(lst, ', ')
images.allow_tags = True
class Tag(models.Model):
tag = models.CharField(max_length=50)
def __unicode__(self):
return self.tag
class Image(models.Model):
title = models.CharField(max_length=60, blank=True, null=True)
image = models.FileField(upload_to="images/")
tags = models.ManyToManyField(Tag, blank=True)
albums = models.ManyToManyField(Album, blank=True)
created = models.DateTimeField(auto_now_add=True)
rating = models.IntegerField(default=50)
width = models.IntegerField(blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(User, null=True, blank=True)
def save(self, *args, **kwargs):
"""Save image dimensions."""
super(Image, self).save(*args, **kwargs)
im = PImage.open(os.path.join(MEDIA_ROOT, self.image.name))
self.width, self.height = im.size
super(Image, self).save(*args, ** kwargs)
def size(self):
"""Image size."""
return "%s x %s" % (self.width, self.height)
def __unicode__(self):
return self.image.name
def tags_(self):
lst = [x[1] for x in self.tags.values_list()]
return str(join(lst, ', '))
def albums_(self):
lst = [x[1] for x in self.albums.values_list()]
return str(join(lst, ', '))
def thumbnail(self):
return """<img border="0" alt="" src="/media/%s" height="40" />""" % (
(self.image.name, self.image.name))
thumbnail.allow_tags = True
def __unicode__(self):
return self.image.name
class AlbumAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["title"]
My views.py
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.forms import ModelForm
from mysite.settings import MEDIA_URL
from photo.models import *
def main(request):
"""Main listing."""
albums = Album.objects.all()
if not request.user.is_authenticated():
albums = albums.filter(public=True)
paginator = Paginator(albums, 10)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
albums = paginator.page(page)
except (InvalidPage, EmptyPage):
albums = paginator.page(paginator.num_pages)
for album in albums.object_list:
album.images = album.image_set.all()[:4]
return render_to_response("photo/list.html", dict(albums=albums, user=request.user,
media_url=MEDIA_URL))
class TagAdmin(admin.ModelAdmin):
list_display = ["tag"]
class ImageAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["__unicode__", "title", "user", "rating", "size", "tags_", "albums_",
"thumbnail", "created"]
list_filter = ["tags", "albums", "user"]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
admin.site.register(Album, AlbumAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(Image, ImageAdmin)
Ok here's the problem why the picture didn't show. You call the incorrect and override the path of the image. Remember you have already put function in your model the thumbnail so in your template you must put only:
<ul>
{% for album in albums.object_list %}
<div class="title">{{ album.title }} ({{ album.image_set.count }} images)</div>
<ul>
{% for img in album.images %}
{{img.thumbnail}}
{% endfor %}
</ul>
{% endfor %}
</ul>
This is correct but my problem is when I test it, the allow tags function has no effect so the output is a link instead of image. So I modified it and got the images show.
{% for img in album.images %}
<a href="{{MEDIA_URL}}{{ img.image}}">
<img border="0" alt="" src="{{MEDIA_URL}}{{ img.image}}" />
</a>
{% endfor %}