I am attempting to create a voting database with an increasing number of names that are never deleted or reset. Votes are cast in the morning, and voting is closed around 10:00. I want to have a separate view that resets the votes back to zero for each instance in the afternoon, after the process is over. How might I accomplish this? Will I have to manually visit this view every day or can it be automated with a DateTime field as the parameter? I have a model to archive old results, but I want to re-use the voting models every day.
class restuarant(models.Model):
name = models.CharField(max_length=50)
votes = models.IntegerField()
percent = models.DecimalField(max_digits=23, decimal_places=20)
def __unicode__(self):
return self.name
class totalVotes(models.Model):
total = models.IntegerField()
class restuarantVote(models.Model):
#voting model for statistic information
choice = models.CharField(max_length=50)
totalVotes = models.IntegerField()
created = models.DateField()
def __unicode__(self):
return self.choice
as andrew suggested resetting data might not be the best approach.
Storing just the raw vote could provide a number of benefits:
you wouldn't have to worry about resetting the data each day. (which could require a cron job to update)
you could analize the data in any way you want.
it is more extendable. You can build more flexible system, suppose you want to add user to the vote to track what a particular user likes?
That way you can see the vote for ANY day not just the current day. You could change up your model:
class Vote(models.Model):
choice = models.CharField(max_length=50)
created = models.DateField(auto_now_add=True)
throughout the day you could just add a vote when one is received
new_vote = Vote(choice=the_choice)
new_vote.save()
then to get the days vote:
todays_count = Vote.objects.filter(choice=the_choice, created=date_obj_here).count()
The best solution to this kind of problem is almost always to eliminate the need for resets entirely. If you can't figure out how to do this conceptually, consider posting more details on your model and application and what you mean by "resetting the votes".
If you absolutely need to run some kind of process daily to clean up your database, you can write a python script and import your application's settings and model file, and then run thej python script with cron on the server. There are a few other too-clever solutions, but almost always you should reconsider your design first.
Edit: now that the code has been added to the question: I recommend you make each restaurantVote represent a single vote cast by a unique individual, and remove the totalVotes IntegerField. Create a new restaurantVote object for each vote cast. You can add a datetime or date field to restaurantVote to mark when it was cast. When you want to total votes, do a query to total up the number of votes for each choice between the beginning and the end of a given day, or just for the given day if you are using a date field instead of a datetime field.
If you don't want to do that, you can keep the IntegerField on there but just add the date field. Every time someone votes, look to see if there is a restaurantVote for that choice and the current day already; if not, then create it (you may be able to use get_or_create() for this).
By the way, if restaurantVote is supposed to be a vote cast for an individual restaurant, then you can use a foreignkey relationship instead of a CharField for choice.
Related
I'm new to django so I'm not sure of the proper way to do things (or the convention).
Say I want to make a project which contains my everyday notes.
I'm going to create multiple notes every day (where each note is going to be an instance of a "Note" model).
I want in my project-frontend to have containers, where I start with containers, each of a specific year (say 2020, 2021, ...) and each of these containers contains month containers (Jan, Feb, ...) and each of those contains day containers (1, 2, ..) and each of those contains the notes of this specific day.
Now my question is should, in my backend, make a NoteYear model which has instances of a NoteMonth model which has instances of NoteDay model which has instances of Note model?
I understand that I can filter the objects by the DateTimeField, and put them in different containers in the frontend (Of course I'll have a DateTimeField for each Note instance anyways).
The reason I thought of this is because it should be faster filtering to get to a specific day.
I'd love to hear your opinions!
Models should not be written based on how to present data at the front-end. Models should try to represent and store data in an effective manner.
Here it would be pure fabrication to create models for the year, month and day items. A simple Note model with a DateTimeField should suffice, especially if you add a database index to that field such that it can easily filter.
Such model thus looks like:
from django.db import models
class Note(models.Model):
note = models.TextField()
created = models.DateTimeField(auto_now_add=True, db_index=True)
You can then effectively retrieve items for a given year, month, day with:
Note.objects.filter(created__year=2021) # year
Note.objects.filter(created__year=2021, created__month=9) # month
Note.objects.filter(created__year=2021, created__month=9, day=25) # day
You may use models as storage objects which means you don't have to define your models based on each and every container.
Accordingly, you may define you models as follows and use django-template to iterate and filter by dates into years/months/days.
class Notes(models.Model):
title = models.CharField(max_length=200)
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(default=timezone.now, blank=True)
I am making a delivery date and time reservation system in django and there I need to implement a reservation system of time and date for the users.
see this UI image here for better understanding
I have to make such a kind of thing that if a user reserves a specific time lets say 9 AM on a specific date and places an order, then that particular time related to that particular date that the user placed an order on will get disabled so that no other user can place an order on that same date and time.
Now, the problem is I am not very sure how to design the database relationships for this feature.
Initially I'm thinking of this model design bellow but I'm sure that it's not that much efficient.
class Date(models.Model):
date = models.DateField()
class Time(models.Model):
time = models.TimeField(auto_now=False, auto_add_now=False)
date = models.ForeignKey('Date', on_delete=models.CASCADE)
Let's assume that one of my users placed an order on 3rd of the month with a delivery time of 10 AM. So according to the system the time '10 AM' on 3rd of the month should get disabled for other users. But the time '10 AM' on other days of the month should still remain open for an order to be placed on.
I don't understand how to do this whole thing with model relationships.
Any help from you guys would be very beneficial for me. Please consider helping me with as much idea as you can.
Thanks.
You can place the time of the order in the order model itself. By setting unique=True you make sure that a specific time is only existing once in the database.
class Order(models.Model):
order_time = models.DateTimeField(null=False, blank=False, unique=True)
You can check if an order with a specific date is already existing by using get
try:
order_exists = Order.objects.get(order_time=time_to_check)
except Order.DoesNotExist:
print('The order is not existing!')
I am building a Django web App that will count the total number of persons entering and exiting a school library in a day, week and year and then save to DB.
The Web App uses a camera that is controlled by OpenCv to show live feed on frontend (I have successfully implemented this already).
My problem is:
How can I design and structure my models to store each data by day, week, month and year?
And how can I query them to display them on different Bar Charts using chart.js?
I haven't used chart.js before but I think I can answer the first part of your question.
Consider this model from one of my projects for a "post" that a user can make on my webapp.
class Post(models.Model):
slug = models.SlugField(unique=True)
title = models.CharField(max_length=100)
description = models.CharField(max_length=2200)
image = models.ImageField(upload_to=photo_path, blank=False, null=True)
timestamp = models.DateTimeField(auto_now_add=True)
Using a "DateTimeField" (or alternatively a "DateField") you can pretty easily store timestamp information which can be filtered using standard python Date or DateTime object comparisons. In my example, I'm storing image files and text information.
For your case you could simply create a new "Person" model where each person is given a timestamp (and whatever other info you might want to store) and then using django querying you can count how many people match certain datetime parameters.
Note the Django Docs (https://docs.djangoproject.com/en/3.1/ref/models/querysets/) recommend :
Don't use len() on QuerySets if all you want to do is determine the number of records in the set. It's much more efficient to handle a count at the database level, using SQL's SELECT COUNT(*), and Django provides a count() method for precisely this reason.
An example of how I'd approach your problem would be:
Models:
class Person(HabitModel):
timestamp = models.DateTimeField(auto_now_add=True)
#whatever extra data you want on each person walking by
#staticmethod
def get_number_of_people(start_timestamp, end_timestamp):
return Person.objects.filter(timestamp__gte=start_timestamp, timestamp__lt=end_timestamp)).count()
(Note the "__gte" and "__lt" are built-in for Django querying and imply [start_timestamp, end_timestamp) inclusive start time and exclusive endtime)
Now you should be able to store your data rather simply and quantify how many people objects were created in whatever timeframe you'd like!
If you can think of a better way to phrase my question, by all means, please change it. Here's the situation I'm facing.
I have 2 models: Agent, Deal. Here's the simplified version of what they look like:
class Agent(models.Model):
name = models.CharField(max_length=100)
price_sum_of_all_deals = models.IntegerField()
class Deal(models.Model):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
address = models.CharField(max_length=100)
price = models.IntegerField()
I'm using celery beat to check an API to see if there are any new deals for each agent. With my current configuration, I am searching for a new deal from within a task method and if I find a deal, I add the price of that deal to the price_sum_of_all_deals field of the corresponding agent. The summary of the task looks likes this:
from celery import shared_task
from agents import models
#shared_task
def get_deals():
agents = models.Agent.objects.all()
for agent in agents:
price, address = get_new_deal_from_api(agent.name)
new_deal = models.Deal(agent=agent, address=address, price=price)
new_deal.save()
agent.price_sum_of_all_deals += price
agent.save()
This, however, is not very intuitive and feels like an unnecessary abstraction. Is there a better way of calculating the price_sum_of_all_deals from within the model? What is the best practice here?
I'm relatively new to Django so if there's something glaring that I overlooked, I apologize.
I don't think that's the best way to process, because if one deal is deleted, how do you update price_sum_of_all_deals? You won't be 100% certain that this value is always accurate (thus, it is not acceptable).
Here is one way to do it, without storing the sum value in an attribute of a model:
use your API as usual,
just create the Deal instance and save it,
to get the sum of all deals of an agent at anytime, you can use the following:
Deal.objects.filter(agent=this_agent).aggregate(price_sum_of_all_deals=Sum('price'))
The result of this line is a dict containing a price_sum_of_all_deals with the desired value.
Source:
https://docs.djangoproject.com/en/3.0/topics/db/aggregation/
https://docs.djangoproject.com/en/3.0/ref/models/querysets/
I hope that is what you needed!
I am gradually replacing a legacy database front end with a django based system. All models are Managed = False, to preserve the original db structure.
However I have struck a problem where a field in a table is computed. The field is defined in (pseudo) sql as full_name = fname|| ||lname.
I can define the full_name field as a charfield; and I can read it no problems, however any attempt to update the record results in an update error on that field.
I can use a #property; but that replicates the functionality in django, rather than displaying the results from the db itself. Using this approach will cause problems with more complex fields (in tables I am yet to get to) that are defined with UDFs.
What is really needed is a 'read_only' or 'computed' attribute on the model itself; what is the best way to achieve this?
Do you just want to define a method in your class? Something like:
def Person(models.Model):
fname=models.CharField(...)
lname=models.CharField(...)
def fullname(self):
return self.fname+" "+self.lname
(not exactly sure what Managed=False means...)
if you are trying to make calculation on a database models and pass the value of a model field to another model field of the same class model, using a defined function then this solution might help you. for example lets assume you have an investment company and you give 20% per month for the capital each user invested, you would want want to pass value from capital model to a function that calculates the percentage interest, and then you will pass that function into another field monthly_payment and get saved in the database.
1) pip install django-computed-property
2) add 'computed_property' to your installed apps in project settings.
3) in your models.py, import computed_property then
class Investment(models.Model):
name = models.CharField(max_length=200)
capital = models.FloatField(null=False)
percentage = models.CharField(max_length=5)
duration = models.CharField(max_length=10, default="1 months")
monthly_payment = computed_property.ComputedFloatField( compute_from='monthly_percentage', null=False, blank=False)
then your function to perform the calculation will go thus
#property
def monthly_percentage(self):
return (20 / 100) * self.capital
Note: what i discovered was if you use the inbuilt django fields be it FloatFiled or IntegerField, this function won't read the amount you are passing in to get your 20% calculations.i hope this works for you as i stated all as they worked for me,cheers.