2

I have been trying to create a way that my Django database will store data for 7 consecutive days because I want to use it to plot a weekly graph but the problem now is that Django doesn't have a datetime field that does that.

'''My Code'''
#Model to save seven consecutive days 
class SevenDayData(models.Model):
 
 '''Stores the date of the latest click and stores the value linked to that date in this case our clicks'''
 day1_date= models.DateField(default=None)
 day1_value= models.CharField(max_length=20)
 
 day2_date= models.DateField(default=None)
 day2_value= models.CharField(max_length=20)
 
 day3_date= models.DateField(default=None)
 day3_value= models.CharField(max_length=20)
 
 day4_date= models.DateField(default=None)
 day4_value= models.CharField(max_length=20)
 
 day5_date= models.DateField(default=None)
 day5_value= models.CharField(max_length=20)
 
 day6_date= models.DateField(default=None)
 day6_value= models.CharField(max_length=20)
 
 day7_date= models.DateField(default=None)
 day7_value= models.CharField(max_length=20)
 
 #updating the model each time the row is saved
 updated_at= models.DateTimeField(auto_now= True)
 
 #function that handles all the saving and switching of the 7 days
 def shift_days(self, new_value):
 
 #getting todays date
 today= date.today()
 
 #shifting every data out from day_7 each time a date is added i.e the 7th day is deleted from the db once the time is due
 self.day7_date, self.day7_value = self.day6_date, self.day6_value #Overwriting each date with the next one
 self.day6_date, self.day6_value = self.day5_date, self.day5_value
 self.day5_date, self.day5_value = self.day4_date, self.day4_value
 self.day4_date, self.day4_value = self.day3_date, self.day3_value
 self.day3_date, self.day3_value = self.day2_date, self.day2_value
 self.day2_date, self.day2_value = self.day1_date, self.day1_value
 
 #writing todays date into the day 1 which actually causes the shifting each time this db is accessed 
 self.day1_date, self.day1_value = today, new_value
 self.save()
'''Error'''
IntegrityError at /go/026099
null value in column "day2_date" of relation "url_shortner_sevendaydata" violates not-null constraint
DETAIL: Failing row contains (1, 2025年09月13日, 11, null, , null, , null, , null, , null, , null, , 2025年09月13日 15:16:30.262801+00).
Request Method: GET
Request URL: http://localhost:8000/go/026099
Django Version: 5.2.1
Exception Type: IntegrityError
Exception Value: 
null value in column "day2_date" of relation "url_shortner_sevendaydata" violates not-null constraint
DETAIL: Failing row contains (1, 2025年09月13日, 11, null, , null, , null, , null, , null, , null, , 2025年09月13日 15:16:30.262801+00).
Exception Location: C:\Users\VICT6OR\Desktop\Coding_backup\self_made.project\mini_url_app\env\Lib\site-packages\django\db\backends\utils.py, line 105, in _execute
Raised during: url_shortner.views.go_to_link
Python Executable: C:\Users\VICT6OR\Desktop\Coding_backup\self_made.project\mini_url_app\env\Scripts\python.exe
Python Version: 3.12.11
Python Path: 
['C:\\Users\\VICT6OR\\Desktop\\Coding_backup\\self_made.project\\mini_url_app',
 'C:\\Users\\VICT6OR\\miniforge3\\python312.zip',
 'C:\\Users\\VICT6OR\\miniforge3\\DLLs',
 'C:\\Users\\VICT6OR\\miniforge3\\Lib',
 'C:\\Users\\VICT6OR\\miniforge3',
 'C:\\Users\\VICT6OR\\Desktop\\Coding_backup\\self_made.project\\mini_url_app\\env',
 'C:\\Users\\VICT6OR\\Desktop\\Coding_backup\\self_made.project\\mini_url_app\\env\\Lib\\site-packages']
Server time: 2025年9月13日 15:16:30 +0000
'''The view giving me the error '''
def go_to_link(request, pk):
 '''Date clicked'''
 today = datetime.date.today()
 '''Clients IP address'''
 x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
 if x_forwarded_for:
 ip = x_forwarded_for.split(',')[0] # first IP = client
 else:
 ip = request.META.get('REMOTE_ADDR')
 # Find the URLModel object
 url_details = URLModel.objects.get(uuid=pk)
 # Increment total clicks
 url_to_edit = URLModel.objects.filter(uuid=pk).first()
 url_to_edit.number_of_times_clicked += 1
 url_to_edit.save()
 # Save new click entry
 new_data = Click(url_relation=url_details, time_clicked=today, ip_address=ip)
 new_data.save()
 # --- Update SevenDayData ---
 record, created = SevenDayData.objects.get_or_create(
 id=1, # global; later you can tie this to url_details if you want per-link tracking
 defaults={
 "day1_date": today,
 "day1_value": str(url_to_edit.number_of_times_clicked),
 }
 )
 # Shift data forward and add today’s new click count
 record.shift_days(str(url_to_edit.number_of_times_clicked))
 return redirect(url_details.long_link)
# function to generate graph so we can analyze our number of clicks
def generate_graph(request, pk):
 # getting the url and the click data for each url
 url_details = URLModel.objects.filter(uuid=pk).first()
 click_details = Click.objects.filter(url_relation__uuid=pk).first()
 if not url_details or not click_details:
 return render(request, "graph.html", {"error": "No data available yet."})
 # getting date and the click count
 date_clicked = click_details.time_clicked
 times_clicked = url_details.number_of_times_clicked
 # Updating the seven day data model
 record, created = SevenDayData.objects.get_or_create(
 id=1,
 defaults={
 "day1_date": date_clicked,
 "day1_value": str(times_clicked),
 }
 )
 # Shift and add today's data if record already exists
 record.shift_days(str(times_clicked))
 # Build data arrays for plotting
 dates = [
 record.day1_date, record.day2_date, record.day3_date,
 record.day4_date, record.day5_date, record.day6_date, record.day7_date
 ]
 values = [
 int(record.day1_value or 0), int(record.day2_value or 0), int(record.day3_value or 0),
 int(record.day4_value or 0), int(record.day5_value or 0), int(record.day6_value or 0),
 int(record.day7_value or 0)
 ]
 # --- Plot the graph ---
 plt.figure(figsize=(8, 5))
 plt.plot(dates, values, marker="o", linestyle="-", color="blue")
 plt.title("Weekly Click Analytics")
 plt.xlabel("Date")
 plt.ylabel("Clicks")
 plt.xticks(rotation=30)
 plt.tight_layout()
 # Convert plot to base64 so we can embed it in HTML
 buf = io.BytesIO()
 plt.savefig(buf, format="png")
 buf.seek(0)
 graph = base64.b64encode(buf.read()).decode("utf-8")
 buf.close()
 # Render your template (graph.html)
 return render(request, "graph.html", {
 "url": url_details,
 "graph": f"data:image/png;base64,{graph}",
 })

Basically I want each time I click a link I want it to save the number of times the link was clicked and save the date at which the particular link was clicked but while saving I get a null error, and with that error I cant also generate a weekly graph analyzing the number of clicks so in summary I want to save daily amount of clicks for seven days but I have a null error

asked Sep 13 at 19:51

1 Answer 1

1

You here try to store None/NULL in the database for non-NULLable fields, you can make these NULLable with:

class SevenDayData(models.Model):
 day1_date = models.DateField(null=True, default=None)
 day1_value = models.CharField(null=True, max_length=20)
 day2_date = models.DateField(null=True, default=None)
 day2_value = models.CharField(null=True, max_length=20)
 day3_date = models.DateField(null=True, default=None)
 day3_value = models.CharField(null=True, max_length=20)
 day4_date = models.DateField(null=True, default=None)
 day4_value = models.CharField(null=True, max_length=20)
 day5_date = models.DateField(null=True, default=None)
 day5_value = models.CharField(null=True, max_length=20)
 day6_date = models.DateField(null=True, default=None)
 day6_value = models.CharField(null=True, max_length=20)
 day7_date = models.DateField(null=True, default=None)
 day7_value = models.CharField(null=True, max_length=20)
 # updating the model each time the row is saved
 updated_at = models.DateTimeField(auto_now=True)

But, a model should not be concerned how to enter data, it should focus on how to store data. You just store single entries, like:

class DayData(models.Model):
 day_date = models.DateField()
 day_value = models.CharField(max_length=20)

so you insert single data.

In case you want to retrieve then data from the last seven days, you can query with:

DayData.objects.filter(day_date__gte=datetime.now().date()-timedelta(days=7))

or if you want the last seven entries with:

DayData.objects.order_by('-day_date')[:7]
answered Sep 13 at 19:56
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.