Django 1.5 select_related defer with multi table inheritance - python

EDIT:
I fixed a few typos below
I added a zip file to a small app to demonstrate this problem here. You can download it and run python manage.py testselectrelateddefer after you syncdb and migrate.
I added a couple of observations below
I fix I am having a multi-table inheritance model as following:
class Image(models.Model):
# other fields are removed for simplicity
image = models.ImageField(upload_to="image")
class ItemImage(Image):
# other fields are removed for simplicity
display_name = models.CharField(max_length=50)
I want to query this model and defer the image field when I don't need the image (which is in the parent model). My container model looks somewhat like this:
class Item(models.Model):
item_image = models.OneToOneField(ItemImage)
The query looks like this:
test.models.Item.objects.select_related('item_image').defer("item_image__image").get(pk=1)
Django is throwing an error saying:
ValueError: u'image_ptr_id' is not in the list.
Django does not throw an error if I query for the field that is not in the parent model:
test.models.Item.objects.select_related('item_image').defer("item_image__display_name").get(pk=1)
Do you know how to fix this issue?
Observations:
As I mentioned above, this only happens if the deferred field is in the parent model; it does not happen if the deferred field is in the child model.
It does not matter if the parents field have any extra field.

Related

Django ManyToManyField Model Manager

In my Python Django 3.7 source code I have the following models:
class ExampleForeignKey(models.Model):
name = models.Charfield(max_length=200)
fields = models.ManyToManyField('ExampleField', related_name='example_foreign_keys')
class ExampleField(models.Model):
name = models.Charfield(max_length=200)
I experience an issue with database duplication when using threading with the source code:
example_field_obj = ExampleField(name='example_field_name')
example_foreign_key_obj = example_field_obj.example_foreign_keys.get_or_create(name='example_foreign_key_name')
I have managed to override the model manager get_or_create() method and applied a multithreading.Lock() in other cases where the model manager is being used directly in the case of direct 1:1 relationships however
I don't know whether it is possible to apply the same principle in the case of ManyToManyField relationships?
Apologies if this has been asked about before elsewhere - I can't seem to find much information on this particular issue.

DRF serialisation issue: combining django-simple-history and django-polymorphic

I am using regular Django models but have now started to incorporate a polymorphic model into my DRF REST API project using django-polymorphic and rest-polymorphic. I am also using django-simple-history to track changes to entries in my database. This all works fine for normal models and polymorphic models without a HistoricalRecords() field, but errors when trying to interact with any polymorphic model that has a HistoricalRecords() field:
django.core.exceptions.FieldError: Cannot resolve keyword 'material_ptr_id' into field.
In my serialiser for the polymorphic models, I use the following technique to serialise the history field:
class HistoricalRecordField(serializers.ListField):
child = serializers.DictField()
def to_representation(self, data):
return super().to_representation(data.values())
class ItemSerializer(serializers.ModelSerializer):
history = HistoricalRecordField(read_only=True)
class Meta:
model = Item
fields = ('history')
Is there a way to exclude the material_ptr_id field from being taken into account by the serialiser as it is not part of the parent model but only the child models? Or are there any obvious other mistakes I am making? Thanks for any help with this.

Constraints when writing Python class

I`m using Python 3.5.2 and Django 1.11 using SQLite
I faced situation where i want to name my model Class with certain name, but with different names I get different results in manage.py migration regarding ForeignKeys
Example from shell:
modules.py
from django.db import models
class Place(models.Model):
question_text = models.CharField(max_length=200)
class Choice(models.Model):
question = models.ForeignKey(Place, on_delete=models.CASCADE)
Running python3 manage.py makemigrations post
Migrations for 'post':
post/migrations/0001_initial.py
- Create model Choice
- Create model Place
- Add field question to choice'
When renaming class Choice into in example "Rating":
from django.db import models
class Place(models.Model):
question_text = models.CharField(max_length=200)
class Rating(models.Model):
question = models.ForeignKey(Place, on_delete=models.CASCADE)
Output of migration attempt:
Migrations for 'post':
post/migrations/0001_initial.py
- Create model Place
- Create model Rating
You might notice that foreign key implementation disappeared. I`ve triple checked it everywhere. Tried with new projects. Stuck with this for a few days. Is there any class naming restrictions or some sort of a bug?
Have a nice holidays, thanks.
It's not a bug, in both cases the foreign key is created.
In the first case, the Choice model is created first, and since Place doesn't exist yet, it can't create the foreign key at the time the model is created. Therefore it is added later in a separate step after the Place model is created.
In the second case, the Place model is created first, so the foreign key can be created in the CreateModel operation for Rating.
Ideally, both cases would produce the second output whenever possible, as it contains less steps, but that optimisation hasn't been implemented yet.

django integrity error, i know why, but dont know how to solve

I changed my former user model so that now it inherits from django's user model.
from django.contrib.auth.models import User
class UserProfile(User):
#fields..
but other models were pointing to my former model and now if i want to migrate, i am getting the error:
(user_id)=(9) does not exist in auth_user table.
reasonable error message. But what should i do now? i am really stuck. i am using django version 1.4
I made a screenshot of the error:
You don't say what version of Django you're using; if you're using 1.5, then you also need to set the AUTH_USER_MODEL setting to tell Django to use it (see the auth docs for more info). If you're on an earlier version, you probably don't want to subclass the User model at all, but create a profile (like your class name indicates) as a separate model and link it with a ForeignKey (see the old profile docs for more on that).
Did you also change the name of the model when you added the parent class? You probably want to set the name of the table in UserProfile so that it matches the old name. From the Django model docs:
To save you time, Django automatically derives the name of the database table from the name of your model class and the app that contains it. A model’s database table name is constructed by joining the model’s “app label” – the name you used in manage.py startapp – to the model’s class name, with an underscore between them.
For example, if you have an app bookstore (as created by manage.py startapp bookstore), a model defined as class Book will have a database table named bookstore_book.
To override the database table name, use the db_table parameter in class Meta.
So something like this would do the trick:
class UserProfile(User):
# other stuff
class Meta:
db_table = "myapp_user"
Hope this helps!

python django one-to-one relations between two models

I have two models and want to set a relation to them.
class ModelA(models.Model):
id = models.IntegerField(primary_key=True) # DB => PK, AI, NN
name = models.CharField(max_length=50)
...
class ModelB(models.Model):
modelA = models.OneToOneField("ModelA", primary_key=True)
description = models.CharField(max_length=255)
...
So I have a relationship between the two models. Is it possible to add a member to ModelA which stores the relation to ModelB without saving this relation to the database?
I would call it a dynamically created relation or something. Any hints oder suggestions how to let both models know each other?
I think it would be benefiting if the relation on one model can be done dynamically. Otherwise I'll get some trouble storing the models because one of the IDs won't be stored if I save one of the models.
I want to have the relation on both models so I can easily use the models as inline in django-admin.
regards
The reverse relation in Django is created by default.
To get the ModelA you will use:
ModelA.objects.filter(modelb__pk = 1)
You will find more details here:
https://docs.djangoproject.com/en/dev/topics/db/queries/
Django ORM will save ModelA first, then ModelB, in order to maintain data integrity in the DB.
Django can try saving multiple items in one transaction, and this way, if you cancel it, nothing will be saved, but this is possible in shell or in Python code. Over HTTP you can't maintain a transaction over several queries so far.
If you need to show model A as inline of model B, you need a custom admin interface, not new fields/models. I can't tell how to write custom admin widgets. I did do a similar thing with custom editor views & templates & Javascript. I stored the unsaved models in request.session.

Categories

Resources