Desciption:
I have a generic function
def gen(model_name,model_type):
objects = model_name.objects.all()
for object in objects:
object.model_type = Null (Or some activity)
object.save()
How Can I achieve the above ? Is it possible?
I would use get_model:
from django.db.models import get_model
mymodel = get_model('some_app', 'SomeModel')
As of Django 1.7 the django.db.models.loading is deprecated (to be removed in 1.9) in favor of the the new application loading system. The 1.7 docs give us the following instead:
$ python manage.py shell
Python 2.7.6 (default, Mar 5 2014, 10:59:47)
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print User
<class 'django.contrib.auth.models.User'>
>>>
if you pass in 'app_label.model_name' you could use contenttypes e.g.
from django.contrib.contenttypes.models import ContentType
model_type = ContentType.objects.get(app_label=app_label, model=model_name)
objects = model_type.model_class().objects.all()
The full answer for Django 1.5 is:
from django.db.models.loading import AppCache
app_cache = AppCache()
model_class = app_cache.get_model(*'myapp.MyModel'.split('.',1))
Related
I have the following model property:
#property
def is_complete(self):
return datetime.datetime.now() >= datetime.datetime.combine(self.date, self.ending_time)
I was wondering, how could I convert this to an annotation, such that:
MyObject.objects.annotate(is_complete=?).filter(is_complete=True)
Would be equiavalent and valid?
You could use ExpressionWrapper to combine the date and time, convert the result to python actual datetime object and finally you can make the comparison.
from django.db.models import DateTimeField, ExpressionWrapper, F
from django.utils import timezone
MyCustomObject.objects.annotate(combine_datetime=ExpressionWrapper(F('date') + F('ending_time'), output_field=DateTimeField())).filter(combine_datetime__lte=timezone.now())
Docs: Django 2.2 Query Expression F with anotation
Try this :
from django.db.models.expressions import Value
from django.db.models.functions.datetime import TruncDate
MyObject.objects.annotate(is_complete=Value(datetime.datetime.now() >= datetime.datetime.combine(TruncDate('date'),TruncDate('ending_time'))))).filter(is_complete=True)
I was trying to give permission using Django guardian. when I try to give permission for existing data its show me a false message but when I create a new object its show me true. what I'm doing wrong?
My code :
>>>from django.contrib.auth.models import User
>>>from print.models import *
>>>from guardian.shortcuts import assign_perm
>>>user = User.objects.create(username='tanvir',password='antu')
>>>excel = ExcelData.objects.all()
>>>assign_perm('delete_exceldata', user, excel)
>>>user.has_perm('delete_exceldata', excel)
>>>False
But If I do
>>>from django.contrib.auth.models import User
>>>from print.models import *
>>>from guardian.shortcuts import assign_perm
>>>user = User.objects.create(username='tanvir',password='antu')
>>>excel = ExcelData.objects.create(order_number='01245632145214')
>>>assign_perm('delete_exceldata', user, excel)
>>>user.has_perm('delete_exceldata', excel)
>>>True
excel = ExcelData.objects.all()
will give you a queryset and
excel=ExcelData.objects.create(order_number='1245632145214')
will give you an object..
You can only assign permission to an object
if you want to assign permission for a queryset do it inside a loop
user = User.objects.create(username='tanvir',password='antu')
excel = ExcelData.objects.all()
for obj in excel:
assign_perm('delete_exceldata', user, obj)
user.has_perm('delete_exceldata', obj) # this will give you status for each obj
Django's callable model field default are broken. When I set a model field default equal to a callable (see migration file below), all models get the same value even though the callable returns different values each time it is called.
This worked on previous fields, so I'm confused why Django would be failing on this field. Everything works up until the point I migrate, when inspecting the database column reveals all values to be the same.
Migration file:
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2018-05-10 14:53
from __future__ import unicode_literals
from django.db import migrations, models
import screen.models
class Migration(migrations.Migration):
dependencies = [
('screen', '0064_employer_enable_show_question_template_tags'),
]
operations = [
migrations.AddField(
model_name='question',
name='key',
field=models.TextField(default=screen.models.generate_question_key),
),
]
Model
def generate_question_key():
# return a random string 64 characters long
return generate_random_hash(64)
class Question(Model):
name = TextField()
points = PositiveIntegerField() # how much it's worth
time_spent = PositiveIntegerField(default = 0) # seconds
score = PositiveIntegerField(default = 0)
key = TextField(default = generate_question_key)
The default returns different values:
>>> import screen
>>> screen.models.generate_question_key()
'JpZzloZkiLyvPLrDZ9764VTWkNUon1FD08mGKODa2uiqW1nV422HXVvt78MsW7aR'
>>> screen.models.generate_question_key()
'NHyTwPDA2cAAsTeIR77INLMM6Ik14EQ6vTlrTv4ZwV56nt6jGEtR8bKn8iyWDeMA'
>>> screen.models.generate_question_key()
'q2aALA7WmvtiKLiGXfNEStpKhOFcNpMDrJ8Y9sv6mwWNsUU6mdgMlgaW5yJJ1yEI'
>>>
It looks like this is a limitation of Django: https://docs.djangoproject.com/en/1.11/howto/writing-migrations/#migrations-that-add-unique-fields
The goal is to update the content of an existent file identified by 'filename'.
The first save call (aStorage.save(filename, ContentFile(content1)) creates the file 'test1'.
The second save call (aStorage.save(filename, ContentFile(content2))) creates a new file (done by Storage.get_available_name) instead of updating the current one.
>>> from django.core.files.storage import FileSystemStorage
>>> from django.core.files.base import ContentFile
>>> import sys
>>> sys.path.append('/home/project1')
>>> import os
>>> os.environ['DJANGO_SETTINGS_MODULE']='project1.settings'
>>> from django.conf import settings
>>> aStorage = FileSystemStorage(location=settings.BASE_DIR)
>>> content1 = "1514 – Mary Tudor (pictured), sister of Henry VIII of England"
>>> content2 = "1874 – The Universal Postal Union, then known as the General Postal"
>>> filename = os.path.join(settings.BASE_DIR, 'tests', 'test1')
>>> aStorage.save(filename, ContentFile(content1))
'./tests/test1'
>>> aStorage.save(filename, ContentFile(content2))
'./tests/test1_ESZ5jdM'
One solution might be this one here:
>>>>if (aStorage.exists(filename)):
>>>> aStorage.delete(filename)
>>> aStorage.save(filename,ContentFile(content2))
`'./tests/test1'`
Is there any other mechanism/workaround to achieve the same functionality ? Thank you.
IF you want to "overwrite" the file, you can go with your own custom Filestorage like this:
class MyFileSystemStorage(FileSystemStorage):
def get_available_name(self, name):
if os.path.exists(self.path(name)):
os.remove(self.path(name))
return name
In this case the file will be deleted so that a file with the same name can be created. This feels like it would be overwritten. Hope this is what you are looking for.
Update:
MyFileSystemStorage is a small custom class which inherits from FileSystemStorage and overwrites the "default" get_available_name function from Djangos FileSystemStorage. You do not need to use this function directly. Its transparently handled if you save a FileObject.
You can use it like this:
aStorage = MyFileSystemStorage(location=settings.BASE_DIR)
If you use MyFileSystemStorage instead of Django FileSystemStorage and save a file with a certain name, an already existing file with that name will be deleted and a new one will be created with the given name. Be careful to use the code like this because any existing file will be "overwritten" if it already exists. If I follow your example correctly you want this behaviour, so I think that it wouldnt not have an impact on your existing code.
It's not clear to me in which situation I can use save method. Therefore, for the moment, I prefer not to change/overwrite the Django Storage.save/get_available_name method behavior. This sounds like another solution to my problem : to use the Storage.open method instead of Storage.save:
>>> content1 = "11111111"
>>> content2 = "22222222"
>>> aStorage
<django.core.files.storage.FileSystemStorage object at 0x7f94ffccc6d0>
>>> fd = aStorage.open("test1.txt","w+")
>>> fd.write(content1)
8
>>> fd.seek(0)
0
>>> fd.read()
'11111111'
>>> fd.close()
>>>
>>> fd = aStorage.open("test1.txt","w+")
>>> fd.read()
''
>>> fd.write(content2)
8
>>> fd.seek(0)
0
>>> fd.read()
'22222222'
>>> fd.close()
>>> aStorage.exists("test1.txt")
>>> True
I will appreciate if you could share with me a situation for the usage of Django's Storage.save method. I am looking here a real case situation. Thanks.
I'm a Django newbie,
I am following a tutorial and I had to create two models shown below:
import datetime
from django.db import models
from django.utils import timezone
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice_text
The following code is from the tutorial. I should get True.
# Make sure our custom method worked.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True
But when I type (same lines as tutorial):
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
I get the following error message:
models.py line 12 in was_published_recently
NameError: global name 'datetime' is not defined..
I imported datetime and timezone... I don't see why I get that error message.
Any help will be appreciated! :-)
You need to import Timezone first from Django utils and after that you need to import datetime.
from django.db import models
from django.utils import timezone
import datetime
Couldn't reproduce the problem, your code works for me.
You could try with something like this:
from datetime import timedelta as tdelta
...
def was_published_recently(self):
return self.pub_date >= timezone.now() - tdelta(days=-1)
In the tests tutorial (part 5), we work on the polls/tests.py file. However, when you run the test, the error complains about the polls/models.py file. This file isn't mentioned in the tests tutorial but you can see it in the error message.
Add from django.utils import timezone to the polls/models.py and try the test again.
If your problem is about Writing your first Django app, part 5, you should add these two lines
import datetime
from django.utils import timezone
Just for clarification this is what I needed to add at the top of my polls/models.py file:
import datetime
from django.utils import timezone
I know this is an older thread. I had the same problem because I forgot to add this line:
from django.utils import timezone
About that error message, please note what Django docs say:
If you encounter an exception querying dates or times, please try installing it before filing a bug. >It’s as simple as:
$ sudo pip install pytz
Once you install the package, the problem will magically go away!
I tried all the things but the problem was still not getting solved. In the end the test worked when I also imported in the same order as mentioned by other in the shell too.
I had to import datetime in the end and only after that it started working.
I got the same issue.
I found out that the Python shell must be reopened after adding import of timezone so the changes would be applied. After that it worked for me.