Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add start date in a rule in admin widget #54

Closed
V1ce opened this issue Sep 21, 2015 · 13 comments
Closed

Add start date in a rule in admin widget #54

V1ce opened this issue Sep 21, 2015 · 13 comments

Comments

@V1ce
Copy link

V1ce commented Sep 21, 2015

Hi,

i want to set event recurrences in the admin widget with a start date but i dont find how to do this, start date of my rules automatically take a datetime.now()

from datetime import datetime
import recurrence


myrule = recurrence.Rule(
    recurrence.DAILY
)

pattern = recurrence.Recurrence(
    dtstart=datetime(2015, 10, 2, 0, 0, 0),
    dtend=datetime(2015, 10, 9, 0, 0, 0),
    rrules=[myrule, ]
)

It thats i want, i got an event started a 2october with daily recurences to 9 october, i check to python dateutil and its easy to do this directly with it too. In your app i really enjoy the admin widget, my users can easy enter complex recursive events with it, but if they can't set a start date will difficult.

in recurrence.fields we can see this : " Field that stores a recurrence.base.Recurrence object to the
database."

Ok i go in base.Recurrence i see this :

`dtstart` : datetime.datetime
        Optionally specify the first occurrence. This defaults to
        `datetime.datetime.now()` when the occurrence set is
        generated.

Im in this case, it generate me an automatic start date.

In recurrences.forms.RecurrenceField :

`accept_dtstart` : bool
            Whether to accept a dtstart value passed in the input.

Im really confuse, how to set a dtstart in the input?

Thanks for your help

@dominicrodger
Copy link
Contributor

You can't do this with the JavaScript widget - if you need to do this, add a DateField to your model, and then use that for generating recurrences.

@V1ce
Copy link
Author

V1ce commented Sep 21, 2015

You mean i have to do something like this ?

class Event(models.Model):
    title = models.CharField(_('title'), max_length=100,unique=True)
    slug = models.SlugField(_('slug'), unique=True,null = True, blank = True)
    start = models.DateField(_('start'))
    end = models.DateField(_('end'))
    recurrences = RecurrenceField()

    def save(self, *args, **kwargs):

        myrule = recurrence.Rule(
        recurrence.DAILY
        )

        pattern = recurrence.Recurrence(
        dtstart=self;start,
        dtend=self.end,
        rrules=[myrule, ]
    )
    self.recurrences = pattern

    super(Event, self).save(*args, **kwargs)

But like this how can i deal with complex recurrences? In this case i dont find the utility of the JavaScript widget if i have to create my own api if i want a start date for my recurrences...

Thanks

@dominicrodger
Copy link
Contributor

No, you can just modify the way you get recurrences back to specify a start date, not the actual recurrence that is saved.

@V1ce
Copy link
Author

V1ce commented Sep 21, 2015

an automatic dtstart is set to datetime.now() when i save my models, there is no way to override this by my start date?

@dominicrodger
Copy link
Contributor

Sure there is - with something like this on your Event model:

def occurrences_between(self, start_date, end_date):
    return self.recurrences.between(start_date, end_date,
                                    dtstart=start_date - timedelta(days=1),
                                    dtend=end_date)

If you don't want an end date, then you can use after. There's some documentation for this which you might find helpful.

@V1ce
Copy link
Author

V1ce commented Sep 21, 2015

Sry i dont understand, if i have this (no end date) :

class Event(models.Model):
    title = models.CharField(_('title'), max_length=100,unique=True)
    slug = models.SlugField(_('slug'), unique=True,null = True, blank = True)
    start = models.DateField(_('start'))
    recurrences = RecurrenceField()
  • i put my start date to 2015-10-02

  • i create a daily recurrence rule with the javascript widget with until at 2015-10-09

  • when i save models thats create me a daily occurence with a start date at 2015-09-21 to 2015-10-09

    i can't override the automatic dtstart set to 2015-09-21 with my own start date?

@dominicrodger
Copy link
Contributor

When you save your model, you create a recurrence rule. You can (and should) override dtstart, per the documentation I linked above, in whatever code you're using to get yourself back a list of dates from a recurrence rule (I presume that's what you're doing - there's not much point storing recurrence information unless you're trying to get some dates out of the rule).

So, in your case, if you want to get a generator of occurrences beginning at the start attribute of your model, you'd do something like this:

def occurrences(self):
    return self.recurrences.after(self.start, dtstart=self.start, inc=True)

@V1ce
Copy link
Author

V1ce commented Sep 22, 2015

Hi,

Thanks,i find a way with the between method, in my case i have a date from a datepicker and want list events with an occurrences for this date so :

models

class Event(models.Model):
    title = models.CharField(_('title'), max_length=100,unique=True)
    date_start = models.DateTimeField(_('start'))
    recurrences = RecurrenceField(null = True, blank = True)

    def occurrences_between(self, start_date, end_date):
            return self.recurrences.between(start_date, end_date,
                                dtstart=self.date_start + timedelta(days=1),inc=True )

views

def get_date1(request,date="2015-10-02"):

    eventDate = datetime.strptime(date,'%Y-%m-%d')
    eventDate = pytz.utc.localize(eventDate)

    event_array = []
    getEvents = Event.objects.all()

    for event in getEvents:

         if event.recurrences and event.occurrences_between(eventDate,eventDate + timedelta(days=1)):

            if not event in event_array: 
                event_array.append(event)

return render(request, 'agenda/date1.html', locals())

But i have a little problem, i dont find a way for include the until date in occurrences, if i set same start_date and until date i got the event at the date, but if my start_date is a 2015-10-02 and until at 2015-10-09, my event stop at 2015-10-08.

Thanks

@dominicrodger
Copy link
Contributor

I'm not quite sure what you're asking here. If your pattern doesn't match 9th October, you won't get 9th October. If you want to manually add the date 9th October, you can always add the date onto your array manually. Or am I misunderstanding what you're trying to do?

@V1ce
Copy link
Author

V1ce commented Sep 22, 2015

sry hard to explain my problems...

I assume that when i enter a daily recurrences for example from 2015-10-02 to 2015-10-09 my event finish at 2015-10-09 not at 2015-10-08.

Or i do something wrong, like you see i add a timedelta(days=1) at dtend parameter in my views when i call event.occurrences_between (i got nothing if i dont add it), and in the Event model method i add it to the dtstart or my event begin 1 day before my start_date...

@V1ce
Copy link
Author

V1ce commented Sep 24, 2015

I have find why i have to add timedelta (days=1) when i call occurrences_between, if my own date_start is at 2015-10-02 00:00 and if i do raise ValueError(self.date_start) during occurences_between, thats return me this : 2015-10-01 22:00:00+00:00 , but if i show my date_start in the templates that return me 2015-10-02, i think i have a timezone problem or something like that...

in my settings i have this :
TIME_ZONE = 'Europe/Paris'
USE_TZ = True

but that change nothing if i delete these lines, i mayble should read some docs for this^^

@V1ce
Copy link
Author

V1ce commented Sep 24, 2015

Problem solve, timezone problem, i set default timezone to utc and just will convert output if needed. Sry for these incomprehensible questions i was so confused with dates and time :p

Last question, set a datetime.now() as default dtstart create so much usless occurrences in my case and i think many others, It would not be better to give us the possibility to set our own dtstart, and if the user want datetime.now he just set himself?

Thanks

@dominicrodger
Copy link
Contributor

Glad you worked it out.

As to changing dtstart, that'd be backwards incompatible, and I'm not convinced it's worth the effort, personally. If someone can come up with a good way to make the change without making upgrading django-recurrence hard, I'd be happy to take a look, but let's handle that elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants