Function does't add data to model(via serializer) - django-models

Here is function I wrote, it checks field called 'url' inside 'Url1' Model and continues IF it's empty.
def mozs():
getids = Url1.objects.values_list('id', flat=True)
for id in getids:
if Url1.objects.get(id=id).pda == None:
authorities= {"pda": 58.26193857945012, "upa": 36.56733779379807}
authorities['keyword'] = id
serializer = MozSerializer(data=authorities)
if serializer.is_valid():
serializer.save()
print "For %d we added %s" % (id, authorities)
Here is output:
For 37 we added {'keyword': 37, 'pda': 58.26193857945012, 'upa': 36.56733779379807}
But it doesn't add it. Here is serializer:
class MozSerializer(serializers.Serializer):
keyword = serializers.PrimaryKeyRelatedField(queryset=KW.objects.all())
pda = serializers.FloatField()
upa = serializers.FloatField()
def save(self):
keyword = self.validated_data['keyword']
pda = self.validated_data['pda']
upa = self.validated_data['upa']
Url1.objects.update(pda=pda, upa=upa)

Related

TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use technicians.set() instead

I keep getting this very same type error even though I am using set. Can someone maybe point out what I'm doing wrong in my api endpoint?
views.py
#require_http_methods(["GET", "POST"])
def api_requerimientos(request):
if request.method == "GET":
requerimientos = FormularioCliente.objects.all()
return JsonResponse(
{"requerimientos": requerimientos},
encoder=FormularioClienteEncoder,
)
elif request.method == "POST":
print("POST REQUEST HIT")
try:
content = json.loads(request.body)
except json.JSONDecodeError:
return HttpResponseBadRequest("Invalid JSON in request body")
requerimiento = FormularioCliente(**content) # Create a new FormularioCliente object
if "technicians" in content and isinstance(content["technicians"], list):
try:
technicians_id_list = content["technicians"]
technicians = Technician.objects.filter(employee_number__in=technicians_id_list)
requerimiento.technicians.set(technicians)
requerimiento.save()
print('requerimiento:', requerimiento)
except Technician.DoesNotExist:
pass
requerimiento.save() # Save the object to the database
models.py
class FormularioCliente(models.Model):
empresa = models.CharField(max_length=21, null=True, unique=True)
titulo = models.CharField(max_length=66)
descripcion = models.CharField(max_length=66)
enlace = models.URLField(null=True)
tipo = models.CharField(max_length=17, choices=TIPO_REQUIRIMIENTO, default="tecnologia")
date = models.DateField(null=True, auto_now_add=True)
time = models.TimeField(null=True, auto_now_add=True)
entrega = models.DateField(null=True)
finished = models.CharField(max_length=19, choices=TIPO_FINALIZACION, default="Abierto")
technicians = models.ManyToManyField(Technician, blank=True)
special_hours = models.SmallIntegerField(default=0)
regular_hours = models.PositiveSmallIntegerField(default=1)
total_hours = models.SmallIntegerField(default=1)
importancia = models.PositiveSmallIntegerField(default=1)
file = models.FileField(upload_to='files', blank=True)
updated = models.DateField(auto_now=True)
def __str__(self):
return f'{self.titulo}: {self.descripcion} # {self.date}'
def technicians_as_json(self):
return list(self.technicians.all().values())
class Technician(models.Model):
name = models.TextField()
employee_number = models.SmallIntegerField(unique=True, primary_key=True)
def __str__(self):
return self.name + " - " + str(self.employee_number)
encoders.py
class TechnicianEncoder(ModelEncoder):
model = Technician
properties = ["name", "employee_number"]
class FormularioClienteEncoder(ModelEncoder):
model = FormularioCliente
properties = [
"id",
"empresa",
"titulo",
"descripcion",
# "user",
"enlace",
# "tipo",
# "File",
"tipo",
"date",
"time",
"entrega",
"finished",
"technicians", # <-- Add this
"special_hours",
"regular_hours",
"total_hours",
"importancia",
"updated",
]
encoders = {"technicians": TechnicianEncoder()}
I also tried to loop through technicians queryset and add it to the instance one by one as well via the add() method but that also didn't work.
I even tried this:
techs = list(requerimiento.technicians.filter(employee_number__in=technicians_id_list).all())
requerimiento.technicians.set(techs)
None of it worked

How to make use of filter using ContentType to check if model instance is already present or not

I am trying to implement like functionality based on this . I want to restrict user to hit like on a event only once. But I am getting the following error. I have added full error details at bottom
Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'
models.py
class ThumbsUpManager(models.Manager):
def create_by_model_type(self, model_type, slug, content, user, parent_obj=None):
model_qs = ContentType.objects.filter(model=model_type)
if model_qs.exists():
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=slug)
if obj_qs.exists() and obj_qs.count() == 1:
instance = self.model()
instance.content = content
instance.user = user
instance.content_type = model_qs.first()
instance.object_id = obj_qs.first().id
if parent_obj:
instance.parent = parent_obj
instance.save()
return instance
return None
class Thumbsup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE)
content = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=True)
objects = ThumbsUpManager()
class Meta:
ordering = ['-timestamp']
def __str__(self):
return str(self.user.username)
#property
def is_parent(self):
if self.parent is not None:
return False
return True
urls.py
urlpatterns = [
path('create/', ThumbsUpCreateAPIView.as_view(), name='create'),
]
view.py
class ThumbsUpCreateAPIView(CreateAPIView):
queryset = Thumbsup.objects.all()
permission_classes = [IsAuthenticated, ]
def get_serializer_class(self):
model_type = self.request.GET.get("type")
slug = self.request.GET.get("slug")
obj_qs = Thumbsup.objects.all()
print(obj_qs)
parent_id = self.request.GET.get("parent_id", None)
return create_thumbs_up_serializer(
model_type=model_type,
slug=slug,
parent_id=parent_id,
user=self.request.user
)
serializers.py
def create_thumbs_up_serializer(model_type=None, slug=None, parent_id=None, user=None):
class ThumbsUpCreateSerializer(ModelSerializer):
class Meta:
model = Thumbsup
fields = [
'id',
'content',
'timestamp',
]
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
self.user = user
if parent_id:
parent_qs = Thumbsup.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(ThumbsUpCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
slug = self.slug
model_qs = ContentType.objects.filter(model=model_type)
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError("This is not a valid content type")
SomeModel = model_qs.first().model_class()
obj_qs = SomeModel.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError("This is not a slug for this content type")
######################### ######################### #########################
How do I need to make query here to check if the user already liked the Event or not?
I tried the following way, but it is not working.
user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
if user_act.exists():
raise ValidationError("You have already liked the event")
return data
def create(self, validated_data):
content = validated_data.get("content")
if user:
main_user = user
else:
main_user = User.objects.all().first()
model_type = self.model_type
slug = self.slug
parent_obj = self.parent_obj
thumbsup = Thumbsup.objects.create_by_model_type(
model_type, slug, content, main_user,
parent_obj=parent_obj,
)
return thumbsup
return ThumbsUpCreateSerializer
Traceback:
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in dispatch
497. response = self.handle_exception(exc)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in handle_exception
457. self.raise_uncaught_exception(exc)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in raise_uncaught_exception
468. raise exc
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in dispatch
494. response = handler(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\generics.py" in post
190. return self.create(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\mixins.py" in create
18. serializer.is_valid(raise_exception=True)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\serializers.py" in is_valid
235. self._validated_data = self.run_validation(self.initial_data)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\serializers.py" in run_validation
433. value = self.validate(value)
File "E:\GIT\test-heroku4\thumbsup\api\serializers.py" in validate
124. user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
File "E:\GIT\blog\backend\venv\lib\site-packages\django\contrib\contenttypes\models.py" in get_for_model
40. opts = self._get_opts(model, for_concrete_model)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\contrib\contenttypes\models.py" in _get_opts
27. model = model._meta.concrete_model
Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'
I checked the model instance before saving in model manager like below and it is working fine. I do not know whether this is the correct way to do the task or not (I'm very new to django. Suggestions are most welcome)
def create_by_model_type(self, model_type, slug, content, user, parent_obj=None):
model_qs = ContentType.objects.filter(model=model_type)
if model_qs.exists():
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=slug)
if obj_qs.exists() and obj_qs.count() == 1:
instance = self.model()
instance.content = content
instance.user = user
instance.content_type = model_qs.first()
instance.object_id = obj_qs.first().id
if parent_obj:
instance.parent = parent_obj
#### Here I have checked for existence before saving the instance ####
if Thumbsup.objects.filter(object_id=instance.object_id, user=instance.user).exists():
raise ValidationError({'already_liked': 'You have already liked the item'})
instance.save()
return instance
return None

How to create data to the database using views

I am trying to create order amount from the catalogue which works like a shopping cart but the amount returned is 1 for all orders made:
views.py
def get_user_pending_order(request):
#get order from correct profile
user_profile = get_object_or_404(Profile,user=request.user)
order = Order.objects.filter(owner=user_profile,is_ordered=True)
if order.exists():
#to get an order in the list of filtered orders
return order[0]
return 0
def add_to_catalogue(request,employee_id):#product_id,employee_id
user_profile= get_object_or_404(Profile, user =request.user)
order_to_purchase = get_user_pending_order(request)
amount= self.order_to_purchase.get_catalogue_total(),
employee = Employee.objects.get(pk=employee_id)
if employee in request.user.profile.ebooks.all():
messages.info(request,'you already own this ebook')
return redirect(reverse('freelance:employee_list'))
order_task,status =
OrderTask.objects.get_or_create(employee=employee)
user_order,status = Order.objects.get_or_create(owner=user_profile,
is_ordered=False,order_amount=amount)####TThis IS WHWERE TO EDIT TO PREVENT
RE ORDERNG OF FREELANCING
user_order.tasks.add(order_task)
if status:
user_order.ref_code = generate_order_id()
user_order.save()
messages.info(request,"task added to catalogue")
return redirect(reverse('freelance:employee_list'))
def get_user_pending_order(request):
#get order from correct profile
user_profile = get_object_or_404(Profile,user=request.user)
order = Order.objects.filter(owner=user_profile,is_ordered=True)
if order.exists():
#to get an order in the list of filtered orders
return order[0]
return 0
models.py
class Order(models.Model):
ref_code = models.CharField(max_length=15)
owner = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=
True)
is_ordered = models.BooleanField(default=False)
tasks = models.ManyToManyField(OrderTask)
date_ordered = models.DateTimeField(auto_now= True)
order_amount = models.DecimalField(default=0.01, max_digits= 10,
decimal_places=2)
def order_tasks(self):
return ','.join([str(c.employee) for c in self.tasks.all()])
def get_catalogue_tasks(self):
return self.tasks.all()
def get_catalogue_total(self):
return sum([task.employee.pricing for task in self.tasks.all()])
def __str__(self):
return '{0} - {1}'.format(self.owner, self.ref_code, self.order_amount)
def tasks_summary(request):
existing_order = get_user_pending_order(request)
my_user_profile = Profile.objects.filter(user=
request.user).first()
my_orders = Order.objects.filter(is_ordered= True, owner=
my_user_profile)
order_to_purchase = get_user_pending_order(request)
amount= order_to_purchase.get_catalogue_total(),
order = Order.objects.filter(is_ordered= True)
context = {
'my_orders':my_orders,
'order':order,
'amount':amount
# 'total':total,
}
return render(request,
'freelance/tasks_summary.html',context)###Belongs to the admin sisde
Output of the template
I am getting this error when I try to add anything to the catalogue:
AttributeError at /admin/tasks_summary/
'int' object has no attribute 'get_catalogue_total'

ValueError: variable needs to have a value for field "id" before this many to many relationship can be used - Django

I created a datamodel in Django, and now I created a script to auto populate the models using web-scraped values. However when I run the script I get the following error:
ValueError: variable needs to have a value for field "id" before this many to many relationship can be used
Models.py
class Books(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Meta:
ordering = ['-title']
class Author(models.Model):
book = models.ManyToManyField(Books)
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=200)
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
class Meta:
ordering = ['last_name','first_name']
class Book_details(models.Model):
book = models.ForeignKey(Books,
on_delete=models.CASCADE,
null=True) # models.SET_NULL weggehaald
pages = models.CharField(max_length=250)
publ_year = models.CharField(max_length=250)
edition = models.CharField(max_length=30) # paperback, hardcover, audiobook, etc
def __str__(self):
return "{} - pages: <{}>, edition: <{}>".format(self.book.title,
self.pages,
self.edition)#
class Cover(models.Model):
book = models.OneToOneField(Books,
on_delete=models.CASCADE)
path = models.CharField(max_length=500)
def __str__(self):
return "<Cover <path={}>".format(self.id, self.path)
populate_script
def add_book(title):
b = Books.objects.get_or_create(title = title)[0]
print(b)
b.save()
return b
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_name = b_author_last)[0]
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]
The scraped_tuple is a return value from the webscraper containing the details.
(Part of) the Traceback:
Books.models.DoesNotExist: Author matching query does not exist.
File "C:\path\to\LibraryApp\Library_WebA
pp\Library\populate.py", line 45, in populate
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_nam
e = b_author_last)[0]
Followed by:
ValueError: "<Author: Mary McCarthy>" needs to have a value for field "id" before this many-to-many relationship can be used.
So, it seems that something goes awfully wrong when trying to execute the new_author statement, because of the many-to-many field "book" in the Author model. How can I resolve this. Do I need a similar function for an Author object like I have for the Book in add_book()?
It seems the new_details statement executes just fine (title and book_details appear correctly in the database in the admin part of Django).
As mentioned in the docs, user .add() to associate the records in many to many field.
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(first_name = b_author_first, last_name = b_author_last)[0]
# add many to many fields this way:
new_author.book.add(new_book)
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]

Can't access model attribute from other model in Django

I need to access an attribute from a related model (to use as a filter attribute in an admin), but I get this error: 'EventTimeAdmin.list_filter[1]' refers to field 'event__sites' that is missing from model 'EventTime'.
Here is are the relevant classes from models.py:
class Event(models.Model):
title = models.CharField(max_length=100)
short_description = models.CharField(max_length=250, blank=True)
long_description = models.TextField(blank=True)
place = models.ForeignKey(Place, related_name="events", default=0, blank=True, null=True)
one_off_place = models.CharField('one-off place', max_length=100, blank=True)
phone = models.CharField(max_length=40)
cost_low = models.DecimalField('cost (low)', max_digits=7, decimal_places=2, blank=True, null=True)
cost_high = models.DecimalField('cost (high)', max_digits=7, decimal_places=2, blank=True, null=True)
age_lowest = models.PositiveSmallIntegerField('lowest age', blank=True, null=True, help_text='Use 0 for "all ages". Leave blank if no age information is available') # Not every event submits info about age limits
priority = models.ForeignKey(EventPriority)
ticket_website = models.URLField('ticket Web site', blank=True)
posted_date = models.DateTimeField('date entered', default=datetime.datetime.now())
updated_date = models.DateTimeField('date updated', editable=False, blank=True)
small_photo = models.ImageField(upload_to='img/events/%Y', blank=True)
teaser_text = models.TextField(max_length=1000, blank=True)
is_ongoing_indefinitely = models.BooleanField(db_index=True, help_text="If this box is checked, the event won't be displayed by default in the event search. Users will have to manually select \"Display ongoing events\" in order to display it.")
is_national_act = models.BooleanField('is a national marquee touring act')
categories = models.ManyToManyField(EventCategory, related_name="events")
bands = models.ManyToManyField(Band, related_name="events", blank=True)
sites = models.ManyToManyField(Site)
related_links = generic.GenericRelation(RelatedLink)
generic_galleries = generic.GenericRelation(GalleryRelationsPiece)
staff_photographer_attending = models.BooleanField('Staff Photographer will be attending')
index = EventIndex()
class Meta:
ordering = ('title',)
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
self.updated_date = datetime.datetime.now()
super(Event, self).save(*args, **kwargs)
def get_absolute_url(self):
if self.is_recurring():
return reverse('ellington_events_ongoing_detail', args=[self.id])
else:
next = self.get_next_time()
if next:
return next.get_absolute_url()
else:
try:
last = self.event_times.order_by("-event_date", "start_time")[0]
return last.get_absolute_url()
except IndexError:
return reverse('ellington_events_todays_events', args=[])
#property
def _sites(self):
"""A property used for indexing which sites this object belongs to."""
return [s.id for s in self.sites.all()]
# def start_time(self):
# return self.event_times.start_time
# TODO: Redundant
def get_absolute_url_recurring(self):
"Returns the absolute URL for this event's recurring-event page"
return reverse('ellington_events_ongoing_detail', args=[self.id])
def is_recurring(self):
"""Returns ``True`` if this event is a recurring event."""
return bool(self.recurring_event_times.count())
def get_cost(self):
"Returns this event's cost as a pretty formatted string such as '$3 - $5'"
if self.cost_low == self.cost_high == 0:
return 'Free'
if self.cost_low == self.cost_high == None:
return ''
if self.cost_low == 0 and self.cost_high == None:
return 'Free'
elif self.cost_low == None and self.cost_high == 0:
return 'Free'
if self.cost_low == self.cost_high:
cost = '$%.2f' % self.cost_low
elif self.cost_low == 0 or self.cost_low == None:
cost = 'Free - $%.2f' % self.cost_high
elif self.cost_high == 0 or self.cost_high == None:
cost = '$%.2f' % self.cost_low
else:
cost = '$%.2f - $%.2f' % (self.cost_low, self.cost_high)
return cost.replace('.00', '')
def get_age_limit(self):
"Returns this event's age limit as a pretty formatted string such as '21+'"
if self.age_lowest is None:
return 'Not available'
if self.age_lowest == 0:
return 'All ages'
return '%s+' % self.age_lowest
def get_place_name(self):
"Returns this event's venue, taking into account the one_off_place field."
if self.one_off_place:
return self.one_off_place
if self.place is not None:
return self.place.name
else:
return ""
def get_next_time(self):
"""
Return the next (in the future) ``EventTime`` for this ``Event``.
Assumes the event is not recurring. Returns ``None`` if no next time is
available.
"""
now = datetime.datetime.now()
for et in self.event_times.filter(event_date__gte=now.date()).order_by("event_date", "start_time"):
try:
dt = datetime.datetime.combine(et.event_date, et.start_time)
except TypeError:
return None
if dt >= now:
return et
return None
# TODO: proprietary
def get_lj_category(self):
"""
Returns either 'Nightlife', 'Music', 'Theater', 'Misc.' or
'Museums and Galleries' for this event.
"""
MAPPING = (
('Activities', 'Misc.'),
('Art', 'Museums and Galleries'),
('Children', 'Misc.'),
('Community', 'Misc.'),
('Culinary', 'Misc.'),
('KU calendar', 'Misc.'),
('Lectures', 'Misc.'),
('Museums', 'Museums and Galleries'),
('Performance', 'Misc.'),
)
# "Performance | Theater" is a special case.
for c in self.categories.all():
if str(c) == "Performance | Theater":
return 'Theater'
parent_categories = [c.parent_category for c in self.categories.all()]
for parent_category, lj_category in MAPPING:
if parent_category in parent_categories:
return lj_category
# Failing that, we must be in either 'Music', which can be either
# 'Music' or 'Nightlife', depending on the venue.
if self.one_off_place:
return 'Music'
# If it's downtown, it's 'Nightlife'. Otherwise, it's 'Music'.
if "downtown" in self.place.neighborhood.lower():
return 'Nightlife'
return 'Music'
class EventTime(models.Model):
event = models.ForeignKey(Event, related_name="event_times")
event_date = models.DateField('date')
start_time = models.TimeField(blank=True, null=True)
finish_time = models.TimeField(blank=True, null=True)
objects = EventTimeManager()
def long_desc(self):
return self.event.long_description
# def sites(self):
# return self.event._sites
# def sites(self):
# return self.event.sites
# #property
# def _sites(self):
# """A property used for indexing which sites this object belongs to."""
# return [s.id for s in self.event.sites.all()]
# def _sites(self):
# """A property used for indexing which sites this object belongs to."""
# return [s.id for s in self.event.sites.all()]
# def _sites(self):
# """A property used for indexing which sites this object belongs to."""
# return [s.id for s in event.sites.all()]
class Meta:
ordering = ('event_date', 'start_time')
def __unicode__(self):
return u"%s -- %s at %s" % (self.event.title, self.event_date.strftime("%m/%d/%y"), self.event.get_place_name())
def get_absolute_url(self):
year = self.event_date.strftime("%Y")
month = self.event_date.strftime("%b").lower()
day = self.event_date.strftime("%d")
return reverse('ellington_events_event_detail', args=[year, month, day, self.event.id])
def get_time(self):
"Returns this event's time as a pretty formatted string such as '3 p.m. to 5 p.m.'"
if self.start_time is not None and self.finish_time is not None:
return '%s to %s' % (dateformat.time_format(self.start_time, 'P'), dateformat.time_format(self.finish_time, 'P'))
elif self.start_time is not None:
return dateformat.time_format(self.start_time, 'P')
return 'time TBA'
def get_part_of_day(self):
"""
Returns a string describing the part of day this event time is taking
place -- either 'Morning', 'Afternoon', 'Evening' or 'Night'.
"""
if self.start_time is None:
return 'Time not available'
if 3 < self.start_time.hour < 12:
return 'Morning'
elif 12 <= self.start_time.hour < 18:
return 'Afternoon'
elif 18 <= self.start_time.hour < 21:
return 'Evening'
return 'Night'
def is_in_the_past(self):
return self.event_date < datetime.date.today()
def happens_this_year(self):
return datetime.date.today().year == self.event_date.year
def get_other_event_times(self):
"Returns a list of all other EventTimes for this EventTime's Event"
if not hasattr(self, "_other_event_times_cache"):
self._other_event_times_cache = [et for et in self.event.event_times.order_by("event_date", "start_time") if et.id != self.id]
return self._other_event_times_cache
# TODO: proprietary
def get_weather_forecast(self):
"Returns a weather.forecast.DayForecast object for this EventTime"
try:
from ellington.weather.models import DayForecast
except ImportError:
return None
if not self.event.place.is_outdoors:
raise DayForecast.DoesNotExist
if not hasattr(self, "_weather_forecast_cache"):
self._weather_forecast_cache = DayForecast.objects.get(full_date=self.event_date)
return self._weather_forecast_cache
DAY_OF_WEEK_CHOICES = (
(0, 'Sunday'),
(1, 'Monday'),
(2, 'Tuesday'),
(3, 'Wednesday'),
(4, 'Thursday'),
(5, 'Friday'),
(6, 'Saturday'),
)
The thing is, event__title is accessed from EventTimeAdmin:
class EventTimeAdmin(admin.ModelAdmin):
list_display = ('event', 'event_date', 'start_time', 'finish_time','long_desc')
list_filter = ('event_date','event__sites')
search_fields = ('event__title', 'event_date')
ordering = ('-event_date',)
class Meta:
model = EventTime
But event__sites is not accessible... why is that?
Edit: You can see my attempts (commented out) to define sites in models.py above. None of these worked.
event__sites is a ManyToManyField
You could try the following:
admin.py
def get_sites(self):
sites = self.event.sites.all()
result = u''
for site in sites:
result = u'%s - %s' % (result, site.name) # unsure about NAME - is it a valid field of Sites Model?
return result
get_sites.short_description = u'Sites'
class EventTimeAdmin(admin.ModelAdmin):
list_filter = ('event_date', get_sites)
admin.site.register(EventTime, EventTimeAdmin)
Hope it helps.

Resources