Home > front end >  Restrict view on utils.py - Django
Restrict view on utils.py - Django

Time:05-23

I've used a tempalte to create a calendar using Django, but now i'm stuck to limit the view of the events on this calendar to just the user who have created the event.

I have no model for this calendar, just for the events, and the calendar is currently based on my util.py file:

utils.py

class Calendar(HTMLCalendar):
    def __init__(self, year=None, month=None):
        self.year = year
        self.month = month
        super(Calendar, self).__init__()

    # formats a day as a td
    # filter events by day
    def formatday(self, day, events):
        contracts_starting_per_day = events.filter(starting_date__day=day)
        contracts_ending_per_day = events.filter(ending_date__day=day)
        contracts_paying_per_day = events.filter(payment_date__day=day)
        d = ''


        for contract in contracts_starting_per_day:
            if contract.company_client:
                client = contract.company_client
            elif contract.person_client:
                client = contract.person_client
            else:
                client = '-'
            d  = f"<a href='http://127.0.0.1:8000/contracts/editct/{contract.id}'> <li class='calendar-li starting' title='{contract.contract_name}'> {contract.contract_name} <p class='calendar-p'> {client} </p> </li> </a>"


        if day != 0:
            return f"<td class='calendar-td'><span class='date'>{day}</span><ul class='calendar-ul'> {d} </ul></td>"
        return "<td class='calendar-td'></td>"

    # formats a week as a tr
    def formatweek(self, theweek, events):
        week = ''
        for d, weekday in theweek:
            week  = self.formatday(d, events)
        return f"<tr class='calendar-tr'> {week} </tr>"

    # formats a month as a table
    # filter events by year and month
    def formatmonth(self, withyear=True):
        contracts = Contract.objects.filter(starting_date__year=self.year, starting_date__month=self.month)

        cal = f'<table border="0" cellpadding="0" cellspacing="0" >\n'
        cal  = f'{self.formatmonthname(self.year, self.month, withyear=withyear)}\n'
        cal  = f'{self.formatweekheader()}\n'
        for week in self.monthdays2calendar(self.year, self.month):
            cal  = f'{self.formatweek(week, contracts)}\n'
        return cal

views.py

class CalendarView(LoginRequiredMixin, generic.ListView):
    model = Contract
    template_name = 'calendar.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Get the actual month to display the calendar
        d = get_date(self.request.GET.get('month', None))
        agenda = Calendar(d.year, d.month)
        html_agenda = agenda.formatmonth(withyear=True)
        #context['calendar'] = context['calendar'].filter(user=self.request.user)
        context['calendar'] = mark_safe(html_agenda)
        context['prev_month'] = prev_month(d)
        context['next_month'] = next_month(d)
        return context


def get_date(req_day):
    if req_day:
        year, month = (int(x) for x in req_day.split('-'))
        return date(year, month, day=1)
    return datetime.today()


def prev_month(d):
    first = d.replace(day=1)
    prev_month = first - timedelta(days=1)
    month = 'month='   str(prev_month.year)   '-'   str(prev_month.month)
    return month

def next_month(d):
    days_in_month = calendar.monthrange(d.year, d.month)[1]
    last = d.replace(day=days_in_month)
    next_month = last   timedelta(days=1)
    month = 'month='   str(next_month.year)   '-'   str(next_month.month)
    return month

I've tried #context['calendar'] = context['calendar'].filter(user=self.request.user) on my views, but i went trough this error:

KeyError at /agenda/calendar 'calendar'

Is there any option to restric the events on the calendar only if the user logged and the user who created the events are equal?

I've also tryed to:

for contract in contracts_starting_per_day:
    if contract.user == request.user:

On my Calendar util, but since this util does not receive any request, it's not possible to use it.

CodePudding user response:

You are trying to retrieve calendar from context while it is not yet in the context. Error is caused in this line:

context['calendar'] = context['calendar'].filter(user=self.request.user)

You should define the queryset for your model in get_queryset method of View. That queryset will be accessible in context in variable you set in context_object_name:

class CalendarView(...):
    ...
    context_object_name = 'contracts'
    def get_queryset(self):
        return Contract.objects.filter(user=self.request.user)

Then in template:

{% for contract in contracts %}
    {{ contract }}
{% endfor %}
  • Related