Django, making a page activate for a fixed time - python

Greetings
I am hacking Django and trying to test something such as:
Like woot.com , I want to sell "an item per day", so only one item will be available for that day (say the default www.mysite.com will be redirected to that item),
Assume my urls for calling these items will be such: www.mysite.com/item/<number>
my model for item:
class Item(models.Model):
item_name = models.CharField(max_length=30)
price = models.FloatField()
content = models.TextField() #keeps all the html content
start_time = models.DateTimeField()
end_time = models.DateTimeField()
And my view for rendering this:
def results(request, item_id):
item = get_object_or_404(Item, pk=item_id)
now = datetime.now()
if item.start_time > now:
#render and return some "not started yet" error templete
elif item.end_time < now:
#render and return some "item selling ended" error templete
else:
# render the real templete for selling this item
What would be the efficient and clever model & templete for achieving this ?

It seems you've got the basics figured out, so I'm assuming you're asking for polishing suggestions... A few ideas in this vein:
I think I'd have a separate URL like /items/today/ for this, or perhaps just /today/.
You'll want to use the date components of datime.datetime.now() only. The whole thing is an object containing the current time specified to a microsecond's precision.
How about using a single base template for all three cases and inheriting from it to change a block containing either the button to click on when buying, the price etc., or a note saying that the item is not being sold yet / any more. Then people can still use the numbered URLs when saying things like See what I bought yesterday, you have to go to that site in an e-mail. ;-)

I have a photo of the day feature on my site. I have a model that represents today's photo, and a cron job runs a custom management command at midnight to update it with the next photo in the sequence (also a model). So all my view has to do is retrieve the current photo from the database.

Related

Safely store data from GET request - Django

Alright,
Let's say we need to create a website with Django where people can book a lodge for the weekends.
We add a search form on the homepage where people can fill in the check-in and check-out date
to filter for all available lodges.
We use a generic Listview to create an overview of all the lodges and we overwrite the queryset to grab the search parameters from the GET request to create a filtered view.
views.py
class ListingsView(ListView):
"""Return all listings"""
model = Listing
template_name = 'orders/listings.html'
def get_queryset(self):
"""
Visitors can either visit the page with- or without a search query
appended to the url. They can either use the form to perform a search
or supply an url with the appropriate parameters.
"""
# Get the start and end dates from the url
check_in = self.request.GET.get('check_in')
check_out = self.request.GET.get('check_out')
queryset = Calendar.objects.filter(
date__gte=check_in,
date__lt=check_out,
is_available=True
)
return queryset
Now this code is simplified for readability, but what I would like to do, is store the check-in and check-out date people are searching for.
Updated views.py
class ListingsView(ListView):
"""Return all listings"""
model = Listing
template_name = 'orders/listings.html'
def get_queryset(self):
"""
Visitors can either visit the page with- or without a search query
appended to the url. They can either use the form to perform a search
or supply an url with the appropriate parameters.
"""
# Get the start and end dates from the url
check_in = self.request.GET.get('check_in')
check_out = self.request.GET.get('check_out')
queryset = Calendar.objects.filter(
date__gte=check_in,
date__lt=check_out,
is_available=True
)
Statistics.objects.create(
check_in=check_in,
check_out=check_out
)
return queryset
We created a "Statistics" model to store all dates people are looking for.
We essentially add data to a model by using a GET request and I'm wondering if this is the right way of doing things? Aren't we creating any vulnerabilities?
The search form uses hidden text inputs, so there's always the possibility of not knowing what data is coming in. Is cleaning or checking the datatype from these input enough, or will this always be in string format?
Any ideas?
Greetz,

How to use django-siteflags to bookmark site objects?

The package is here and here but I cannot get it to work.
Here is my models.py file
class Video(models.Model, ModelWithFlag):
name = models.CharField(max_length=255)
file = models.FileField(upload_to="static/videos/", null=True, verbose_name="", unique=True)
def __str__(self):
return self.name
And the views.py file
def user_bookmarked_video(request, bookmark_id):
video = get_object_or_404(Video, pk=bookmark_id)
# Now a user adds this article to his bookmarks.
video.set_flag(request.user)
How should the urls.py and .html look like ?
The most of the question is not related to siteflags itself.
See "Writing more views" to have an example of urls.py.
For example, it might look like
path('videos/<int:bookmark_id>/', views.user_bookmarked_video, name='videos_bookmarked'),
However your bookmark_id is missleading, since it's a video ID, not a bookmark ID. Moreover your view is named user_bookmarked_video(), but it's not what it does — it just sets a flag (bookmark) on some video object.
If you plan to use this view just to set a bookmark you'd better name it like set_video_bookmark() and redirect at the end of the function, instead of html rendering.
If your intention was to show all bookmarked videos for current user then there's no need to accept bookmark_id argument for your view and flagging on every view call.
Your html may look like as you want, depending on what do you want to see.
For example:
<h1>{{ video.name }}</h1>

Changing user data in django python

guys! I'm new to django and I'm developing simple web site with user registration. I want to test some things, for example: on user profile page I added picture:
and by pressing on it picture should change to:
And by pressing on red one it should be changed to grey.
Condotion of this picture should be saved. I have seven pictures for every day of the week and user should be able to change every picture.
I've created a model like this (if you have any better ideas it would be great):
class Week1(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
utr_ust0 = models.IntegerField(default=0, max_length=3)
utr_ust1 = models.IntegerField(default=0, max_length=3)
utr_ust2 = models.IntegerField(default=0, max_length=3)
...
utr_ust0 = 0 (grey)
utr_ust0 = 1 (red)
But I cant't really understand how to work with this model in views. I think that during registration I should do something like this:
auth.login(request, user)
Week1.objects.create(utr_ust0=0, utr_ust1=0, utr_ust2=0, utr_ust3=0,
utr_ust4=0, utr_ust5=0, utr_ust6=0, user_id=username)
But I get this error: invalid literal for int() with base 10: 'test5'
And in the function that loads page with the calendar I'm returning dict like this:
if request.user.is_authenticated:
content['smiles'] = [Week1.utr_ust0, Week1.utr_ust1, Week1.utr_ust2,
Week1.utr_ust3, Week1.utr_ust4, Week1.utr_ust5, Week1.utr_ust6]
And of course I should add some ajax script but I dont' now yet how to do this.
Any ideas or advices? Thank you a lot.
...utr_ust6=0, user_id=username)
user_id should be a user ID, an int, or pass the object:
week1.objects.create(..., user=user)
check the type of user in auth.login(..) or pick it from the request if it's available: request.user

Django save behaving randomly

I have a Story model with a M2M relationship to some Resource objects. Some of the Resource objects are missing a name so I want to copy the title of the Story to the assigned Resource objects.
Here is my code:
from collector import models
from django.core.paginator import Paginator
paginator = Paginator(models.Story.objects.all(), 1000)
def fix_issues():
for page in range(1, paginator.num_pages + 1):
for story in paginator.page(page).object_list:
name_story = story.title
for r in story.resources.select_subclasses():
if r.name != name_story:
r.name = name_story
r.save()
if len(r.name) == 0:
print("Something went wrong: " + name_story)
print("done processing page %s out of %s" % (page, paginator.num_pages))
fix_issues()
I need to use a paginator because I'm dealing with a million objects. The weird part is that after calling fix_issues() about half of my resources that had no name, now have the correct name, while the other half still has no name. I can call fix_issues() again and again and every time more objects receive a name. This seems really weird to me, why would an object not be updated the first time but only the second time?
Additional information:
The "Something went wrong: " message is never printed.
I'm using select_subclasses from django-model-utils to iterate over all resources (any type).
The story.title is never empty.
No error message is printed, when I run these commands.
I did not override the save method of the Resource model (only the save method of the Story model).
I tried to use #transaction.atomic but the result was the same.
My Model:
class Resource(models.Model):
name = models.CharField(max_length=200)
# Important for retrieving the correct subtype.
objects = InheritanceManager()
def __str__(self):
return str(self.name)
class CustomResource(Resource):
homepage = models.CharField(max_length=3000, default="", blank=True, null=True)
class Story(models.Model):
url = models.URLField(max_length=3000)
resources = models.ManyToManyField(Resource)
popularity = models.FloatField()
def _update_popularity(self):
self.popularity = 3
def save(self, *args, **kwargs):
super(Story, self).save(*args, **kwargs)
self._update_popularity()
super(Story, self).save(*args, **kwargs)
Documentation for the select_subclasses:
http://django-model-utils.readthedocs.io/en/latest/managers.html#inheritancemanager
Further investigation:
I thought that maybe select_subclasses did not return all the objects. Right now every story has exactly one resource. So it was easy enough to check that select_subclasses always returns one item. This is the function I used:
def find_issues():
for page in range(1, paginator.num_pages + 1):
for story in paginator.page(page).object_list:
assert(len(story.resources.select_subclasses()) == 1)
print("done processing page %s out of %s" % (page, paginator.num_pages))
But again, this executes without any problems. So I don't thing the select_subclasses is to blame. I also checked if paginator.num_pages is right and it is. If i divide by 1000 (items per page) I get exactly the number of stories I have in my database.
I think I know what is happening:
The Paginator loads a Queryset and gives me the first n items. I process these and update some of the values. But for the next iteration the order of the items in the queryset changes (because I updated some of them and did not define an order). So I'm skipping over items that are now on the first page. I can avoid it by specifying an order (pk for example).
If you think I'm wrong, please let me know. Otherwise I will accept this as the correct answer. Thank you.

Merge fields in user created email templates in django

So I'm going to have users type up a draft document for email confirmation for a booking application. This draft could look something like this:
Dear [contactname],
This is your booking confirmation for your vacation from [startdate] to [enddate] for a total of [numdays] days.
Please click [cancellink] to cancel your booking.
An email only makes sense in relation to a booking object. Currently I have a method that takes a booking object and a merge string and decides what to do like:
def merge_field(booking, ms):
if ms == 'contactname':
return booking.contactsheet.name
elif ms == 'startdate':
return str(booking.firstday)
elif ms == 'enddate':
return str(booking.lastday)
elif ms == 'numdays':
return str((booking.firstday - booking.lastday).days + 1)
elif ms == 'cancellink':
return 'cancel'
This hardcoded approach is pretty ugly. I would much rather prefer to have the users supply a string I could parse and infer some meaning like references into the booking object, some arithmetic and static strings (like in the link). I imagine a model like:
class MergeField(models.Model):
name = models.CharField(max_length=100)
formula = models.TextField()
Then the users could design and test their own merge fields and use them in the email templates. This would make it much easier to maintain. However, I have no idea how I would parse this formula field.
Do you have any idea how to do this?
A better solution would be to use the django template system. Have the user enter the message in django template format like:
Dear {{contactname}},
This is your booking confirmation for your vacation from {{startdate}} to {{enddate}} for a total of {{numdays}} days.
Please click {{cancellink}} to cancel your booking.
And then use get_template_from_string from django.template.loader and get a template instance. Than you can render the template by doing template.render(context), Where context is a Context instance found in django.template.context.
You can read more about django template api in https://docs.djangoproject.com/en/1.6/ref/templates/api/ Should be simple from here.

Categories

Resources