I have a model such as the following:
class Item(models.Model):
name = models.CharField(max_length=150)
created = models.DateTimeField(auto_now_add=True)
the admin class is the following:
class ItemAdmin(admin.ModelAdmin):
list_display = ('name', 'created')
the created field does not seem to exist
Is there some basic Django knowledge that I am missing or have forgotten?
When you say the field does not exist, do you mean that it is not showing on the admin change form? This is expected behaviour when using auto_now_add. If you want the field to get a default value on creation but still be editable, use default=datetime.datetime.now instead.
Strange. I tried out your example and it worked perfectly well (Django 1.2.1, Python 2.6.2)
Can you verify that:
The field exists in the database (fire a SQL query perhaps)
Check your admin.py (again) for any differences.
Update
#Daniel's answer is more likely to help the OP.
Just make sure not to forget registering the ItemAdmin in admin.py:
admin.site.register(Item, ItemAdmin)
However, the 'created' field would only be displayed in the Item's list page, as well as if you add an additional field such as:
updated = models.DateTimeField(auto_now=True)
Related
I am running Django on Heroku with zero-downtime feature. This means that during deployment there are two version of code running (old and new) on the same database. That's why we need to avoid any backward incompatible migrations.
It there a possibility to exclude a field from Django query on a given model?
Let say we have a model (version 1):
class Person(models.Model):
name = models.CharField()
address = models.TextField()
In some time in the future we want to move address to the separate table. We know that we should not delete a field for older code to work so Person model may look like (version 2):
class Person(models.Model):
name = models.CharField()
address = models.ForeignKey(Address)
_address = models.TextField(db_name='address')
This way if old code will query for address it will get it from Person table even if database has been migrated (it will be an old value, but let assume thats not a big issue).
How now I can safetly delete _address field? If we will deploy version 3 with _address field deleted then code for version 2 will still try to fetch _address on select, even if it's not used anywhere and will fail with "No such column" exception.
Is there a way to prevent this and mark some field as "non-fetchable" within the code for version 2? So version 2 will not delete field, but will not fetch it anymore and version 3 will delete field.
You can use custom object manager for defer your specific field/fields for all the queryset.
class CustomManager(models.Manager):
def get_queryset(self):
return super(CustomManager, self).get_queryset().defer('_address',)
class Person(models.Model):
name = models.CharField()
address = models.ForeignKey(Address)
_address = models.TextField(db_name='address')
objects = CustomManager()
after that in your any queryset against Person model will not include _address field in query by default.
Yes, you can do it:
QuerySet.defer():
"In some complex data-modeling situations, your models might contain a lot of fields, some of which could contain a lot of data (for example, text fields), or require expensive processing to convert them to Python objects. If you are using the results of a queryset in some situation where you don’t know if you need those particular fields when you initially fetch the data, you can tell Django not to retrieve them from the database." - docs
Entry.objects.defer("headline", "body")
OR
With django 1.8 onwards: use values_list. You can only include fields that you want. You can also use Queryset.only() and Queryset.defer() to refine your queryset queries. You can chain defer() calls as well
Entry.objects.values_list('id', 'headline')
I'm quite new to Python and Django. I'm setting up a new model class and I'm able to add appointments on the admin page, but here's the strange thing:
I used to have a DateTimeFiled, which I changed to a separate DateField and a TimeField. But now I see neither my DateField nor my TimeField. Why is that, I don't understand it. I've done the migration, everything looks right.
This is my model class:
class Appointment(models.Model):
patient = models.ForeignKey(User, related_name="appointment_patient", on_delete=False)
date = models.DateField(auto_now=True)
start_time = models.TimeField(auto_now=True)
duration = models.DurationField(default=timedelta(minutes=30))
Before I made this change every property came out right, but now this happens:
auto_now automatically updated with timezone.now() whenever the model object is saved also its not editable. So its not necessary to display them in the template. That is why adminsite omits this field or does not show it. Please see the documentation for more details. If you want to display this field then add it readonly_fields. For example:
class YourModelAdmin(admin.ModelAdmin):
readonly_fields=('start_time',)
Update
If you want to add default value to DateField, try like this:
import datetime
# in models
state_date = models.DateField(default=datetime.date.today) # without parenthesis
I' ve the following simplified model structure:
#common/models.py
class CLDate(models.Model):
active = models.BooleanField(default=True)
last_modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
#br/models.py
class Dokument(CLDate):
user = models.ForeignKey(User)
class Entity(CLDate):
dokument = models.ForeignKey(Dokument)
. Both class inherits from CLDate, and i' ve a OneToMany relation between them. When i try to migrate, i got the following error:
python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
br.Entity.dokument: (models.E006) The field 'dokument' clashes with the
field 'dokument' from model 'common.cldate'.
I can' t really get why is this structure a problem for Django hence the Entity is a totally different object than the Dokument. Could anyone explain me why, and how could i solve it with this structure? So both should inherit from CLDate and there should be this kind of relation between the 2 models from the br application.
I also tried to delete all the migration files, and solve it that way, but the same. Runserver gives also this error.
Django: 1.11.2
Python: 3.4.2
Debian: 8.8
.
Thanks.
If i rename the dokument property name in the Entity model, it works fine.
I' m also almost pretty the same layout was working previously (in previous Django versions).
Since you are using multi-table inheritance, Django creates an implicit one-to-one field from Dokument to CLDate. The reverse relation dokument from CLDate to Dokument is clashing with your Entity.dokument field.
If you don't want to rename your Entity.dokument field, then your other option is to explicitly define the parent link field from Dokument to CLDate and set related_name.
class Dokument(CLDate):
cl_date = models.OneToOneField(CLDate, parent_link=True, related_name='related_dokument')
user = models.ForeignKey(User)
I thought I would up my python game with Django a bit by developing a large scale business app for fun. I seen the need for a common ancestor approach to model inheritence and tried to implement it based on the official documentation. However, I keep getting this very annoying Message which I'm not sure what to do with.
Dj Version: Django 1.7
Py Version: Python 3.4.2
Message
$ python manage.py makemigrations
You are trying to add a non-nullable field 'businessentity_ptr' to business without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Models.py
class BusinessEntity(models.Model):
title = models.CharField(max_length=180)
def __str__(self):
return self.title
class Business(BusinessEntity):
description = models.TextField(max_length=600)
claimed = models.BooleanField(default=False)
slug = models.SlugField()
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return self.description
What I've Tried, (which everyone will hate):
Deleting the DB & Re-migrating
setting a default value for all fields
Setting all fields to null = True
I have seen a hack around for this but I don't think it's a good approach. Maybe there is someone out there who understand Django Common Ancestors much better and point me in the right direction.
Since your parent model is intended to be abstract, you should mark it as such.
class BusinessEntity(models.Model):
title = models.CharField(max_length=180)
class Meta:
abstract = True
This prevents Django from creating a separate table for it, and therefore needing a _ptr field to point back to it from the subclass. Instead, the table for your subclass will be created to include the inherited field(s) directly.
I'm working on what I think is a pretty standard django site, but am having trouble getting my admin section to display the proper fields.
Here's my models.py:
class Tech(models.Model):
name = models.CharField(max_length = 30)
class Project(models.Model):
title = models.CharField(max_length = 50)
techs = models.ManyToManyField(Tech)
In other words, a Project can have different Tech objects and different tech objects can belong to different Projects (Project X was created with Python and Django, Project Y was C# and SQL Server)
However, the admin site doesn't display any UI for the Tech objects. Here's my admin.py:
class TechInline(admin.TabularInline):
model = Tech
extra = 5
class ProjectAdmin(admin.ModelAdmin):
fields = ['title']
inlines = []
list_display = ('title')
admin.site.register(Project, ProjectAdmin)
I've tried adding the TechInline class to the inlines list, but that causes a
<class 'home.projects.models.Tech'> has no ForeignKey to <class 'home.projects.models.Project'>
Error. Also tried adding techs to the fields list, but that gives a
no such table: projects_project_techs
Error. I verified, and there is no projects_project_techs table, but there is a projects_tech one. Did something perhaps get screwed up in my syncdb?
I am using Sqlite as my database if that helps.
I've tried adding the TechInline class to the inlines list, but that causes a
'TechInLine' not defined
Is that a straight copy-paste? It looks like you just made a typo -- try TechInline instead of TechInLine.
If your syncdb didn't create the proper table, you can do it manually. Execute this command:
python manage.py sqlreset <myapp>
And look for the definition for the projects_project_techs table. Copy and paste it into the client for your database.
Assuming your app is called "projects", the default name for your techs table will be projects_tech and the projects table will be projects_project.
The many-to-many table should be something like projects_project_techs
#John Millikin - Thanks for the sqlreset tip, that put me on the right path. The sqlreset generated code that showed me that the projects_project_techs was never actually created. I ended up just deleting my deb.db database and regenerating it. techs then showed up as it should.
And just as a sidenote, I had to do an admin.site.register(Tech) to be able to create new instances of the class from the Project page too.
I'll probably post another question to see if there is a better way to implement model changes (since I'm pretty sure that is what caused my problem) without wiping the database.