Django form DateField initial value not updating in Apache - django

I have a Django form that includes a DateInput like this:
Fecha = forms.DateField(widget=DateInput(format = '%Y-%m-%d'),initial=(date.today() - timedelta(1)))
The idea is that every time you access the template that contains the form, it automatically shows the day-1 date.In my development environment this works as expected.However, I've noticed something strange in my production environment. The DateField initial value doesn't change unless I restart my Apache Server. For example, if I restart Apache right now my form will show 2015-02-26 as the initial date and will stay like that until I restart Apache again. I'm not sure if this is Django related or it has more to do with Apache configuration. Any suggestions or workarounds? Thanks in advance!!!!
Regards,
Alejandro

Shouldn't it be like this:
def get_yesterday():
return datetime.today() - timedelta(days=1)
mydatefield = forms.DateField(widget=DateInput(format = '%Y-%m-%d'),initial=get_yesterday)
Your code would evaluate the date.today() function at server initialization and not at form initialization.

This is neither a django issue nor an Apache configuration problem, but rather a result of how and when Python evaluates code. Class attributes are evaluated as soon as the module containing a class is imported/brought into memory. So your form class's Fecha attribute is evaluated only initially when your app starts, and not evaluated again until your app is restarted.
To handle this, simply provide initial date values when your view instantiates your form object instead of in your form class definition. This will work because your view function executes every time you refresh the page:
import MyForm
def my_view(request):
my_form_instance = MyForm(initial={'Fecha': date.today() - timedelta(1)})
...

Related

Django - form's ChoiceField not updating immediately

I have created a form in forms.py which uses select input based on objects from the database:
from controls.models import Valve
class CronjobForm(forms.Form):
query = Valve.objects.all()
VALVE_CHOICES = [
(valve.pk, valve.name) for valve in query
]
valves = forms.ChoiceField(required=True, widget=forms.Select, choices=VALVE_CHOICES)
At first, everything seemed to work just fine, the HTML's <select> with option got rendered.
The problem is, when I add a new Valve object to the database, using the Django Admin interface, it takes a while for the ChoiceField field to get updated - I can't see the new option on front-end immediately. I tried to reload the page, force reload, even print out the query to the terminal - the variable query got updated immediately, just the HTML did not.
It eventually gets updated after a while, minute or so, maybe thanks to the system checks or by repeating the runserver command.
So I'm wondering, what am I missing? Is there some way to force update the form? Does the form get cached and that's what causes the problem?
This is because the query is being evaluated when the class is defined, not when the form is instantiated.
Don't do this. Use a ModelChoiceField, which accepts a queryset.
class CronjobForm(forms.Form):
valves = forms.ModelChoiceField(required=True, widget=forms.Select, queryset=Valve.objects.all())
We can also pass a reference of the function which will return the array for choices, as mentioned in the choices' description of django docs.
I also faced the same issue, which was resolved like this.
def get_valve_choices():
return [
(valve.pk, valve.name) for valve in Valve.objects.all()
]
class CronjobForm(forms.Form):
valves = forms.ChoiceField(required=True, widget=forms.Select, choices=get_valve_choices)

Disable validation when calling manage.py

Is it possible, to skip the validation when calling manage.py?
During development i have to reset my database from time to time an initialize data with "manage.py loaddata ...".
In one of my template views i have following code:
class CharterModalEmailOption(MessagesMixin, CharterMixin, TemplateView):
footer_template = Mailtemplate.objects.get(slug='signatur')
manage.py fails with the message "Mailtemplate matching query does not exist." That's right, because the table is empty at this stage and i want to add entries with loaddata. So as long as manage.py validates my views i cannot add the data. Looks like a dead end.
I can solve the problem by defining "footer_template" inside class functions and not at class level.
Does anybody have an idea?
Thank you,
Andreas
You shouldn't ever set a field directly to a queryset, and instead you should use a constructor.
Doing it directly will mean this is only ever done when the class is first referenced which may result in outdated information.
Simply just provide a constructor so this field is only initialized when you create an instance of the class
class CharterModalEmailOption(MessagesMixin, CharterMixin, TemplateView):
def __init__(self, *args, **kwargs):
self.footer_template = Mailtemplate.objects.get(slug='signatur')

Getting random object of a model with django-rest-framework

In my Django project I need to provide a view to get random object from a model using django-rest-framework. I had this ListAPIView:
class RandomObject(generics.ListAPIView):
queryset = MyModel.objects.all().order_by('?')[:1]
serializer_class = MyModelSerializer
...
It worked fine but order_by('?') takes a lot of time when launched on big database. So I decided to use usual Python random.
import random
def pick_random_object():
return random.randrange(1, MyModel.objects.all().count() + 1)
class RandomObject(generics.ListAPIView):
queryset = MyModel.objects.all().filter(id = pick_random_object())
...
I found out a strange thing when tried to use this. I launched Django development server and sent some GET requests, but I got absolutely the same object for all of the requests. When dev server restarted and another set of requests sent I'm getting another object, but still absolutely the same one for all of requests - even if random.seed() was used first of all. Meanwhile, when I tried to get a random object not via REST but via python manage.py shell I got random objects for every time I called pick_random_object().
So everything looks good when using shell and the behavior is strange when using REST, and I have no clue of what's wrong.
Everything was executed on Django development server (python manage.py runserver).
As #CarltonGibson noticed, queryset is an attribute of RandomObject class. Hence it cached and cannot be changed any later. So if you want to make some changeable queryset (like getting random objects at every request) in some APIView, you must override a get_queryset() method. So instead of
class RandomObject(generics.ListAPIView):
queryset = MyModel.objects.all().filter(id = pick_random_object())
...
you should write something like this:
class RandomObject(generics.ListAPIView):
#queryset = MyModel.objects.all().filter(id = pick_random_object())
def get_queryset(self):
return MyModel.objects.all().filter(id = pick_random_object())
Here pick_random_object() is a method to get random id from the model.
Since it's an attribute of the class, your queryset is getting evaluated and cached when the class is loaded, i.e. when you start the dev server.
I'd try pulling a list of primary keys, using values_list() — the flat=True example does exactly what you need. Ideally cache that. Pick a primary key at random and then use that to get() the actual object when you need it.
So, how would that go?
I'd define a method on the view. If you forget the caching, the implementation might go like this:
# Lets use this...
from random import choice
def random_MyModel(self):
"""Method of RandomObject to pick random MyModel"""
pks = MyModel.objects.values_list('pk', flat=True).order_by('id')
random_pk = choice(pks)
return MyModel.objects.get(pk=random_pk)
You might then want to cache the first look up here. The caching docs linked above explain how to do that. If you do cache the result look into the db.models signals to know when to invalidate — I guess you'd post_save, checking the created flag, and post_delete.
I hope that helps.

django model set field default value from admin panel

models.py
class MyModel(models.Model):
maximum_limit = models.PositiveIntegerField(default=5)
Here I set maximum_limit default value is 5.
But I want to set a value which is also editable from admin and use here as a default value. (editable default value for model MyModel)
My initial approach is(not working). I want something like this.
class MySettings(models.Model):
mx_limit = models.PositiveIntegerField(default=5)
class MyModel(models.Model):
maximum_limit = models.PositiveIntegerField(default=MySettings.mx_limit)
Please help me
Your approach is wrong, a maximum for a db value should be set with the proper attribute, namely max_value.
However this would require a schemamigration everytime you want to change it. So what you really should be doing is dynamic form validation where your form checks for a setting (which should probably be saved in your database and not be statically stored in a module like Settings, which would require server restarts).
There are plenty examples how to make a form validation more dynamically on stackoverflow

Object label in GAE Django

In my usual django code I use the unicode function to give each object a label...this appears in the admin interface as the oject label in the objects listed...
class apprd(models.Model):
usr = models.ReferenceProperty(User)
approved = models.BooleanProperty(default = True)
def __unicode__(self):
return ('approved one')
but now i have moved to GAE and this feature does not seem to be supported...
is there any work around or am I doin a mistake
This isn't possible in GAE, because the GAE admin console does not read - indeed, has no access to - your model definitions. It only has access to the stored data.
If you use http://code.google.com/p/app-engine-patch/, you can get the full Django admin interface running inside GAE.