Multiple Data Entry in Django ORM

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:    Sat, 13 Sep 2025 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

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]
Вернуться на верх