Differences between one-to-one and foreign key relationships? - django

Can someone explain the significance of specifying a relationship in a Django model as one-to-one as opposed to just a foreign key?
Specifically, I'm wondering what advantages you get from specifying a relationship as 1-1, if any.
Thanks so much.

The OneToOneField evolved in Django after 'ForeignKey'. Conceptually a ForeignKey with unique=True constraint is similar to OneToOneField.
So if you want to ensure that every picture has one user and vice-versa use a OneToOneField.
If you want one user to have any number of pictures use a ForeignKey.
The way things are selected are also different. In case of doing OneToOneField, you can do user.picture and get the picture directly. In case of ForeignKey you will do user.picture_set[0] to get the first picture or access all the pictures associated with that user.
MultiTableInheritance implicitly uses OneToOneField internally and you can see where the concept originated from.

The additional constraints of a 1-1 provide a tighter and richer conceptual model but can also provide insight that can allow for more intuitive retrieval. As a many to one represents a parent/collection relationship there is an unclear cost associated with the retrieval of any given collection for a particular entity. Since a 1-1 provides a flat mapping there is also a flat cost of retrieval. This would lead to things like preferring eager fetching when relevant, as the join will be be able to be easily optimized and the resultant data set will be a known size.

They are not the same; think about it:
If you have a one-to-one relationship between a User and a Picture, you are saying that a user can only have one picture (and a picture can only have one user). If you were to have a Picture with foreign key to User, then you are saying that a picture must have exactly one user, but a user may have 0, 1 or many pictures.

Django's Foreign Key is a many to one relationship. Now, the difference between them is the same as the difference between a One-To-One and Many-To-One relationship. For example, if you have User and Profile entities. You would like to add a constraint that each User could have one and only one Profile. Then, using a django's one to one field would create a restriction on the database level so, that you won't be able to relate User to multiple Profiles or vice-versa. Where as using Foreign Key wouldn't provide this constraint.

Related

Django Many to Many - polymorphic

In a Django application, I have three models:
Service
Product
AppliedTax
I want to create a many-to-many relationship between Service and AppliedTax and between Product and AppliedTax. Normally I would have an intermediate model (i.e. AppliedTaxTaxable) with three fields (applied_tax_id, taxable_type and taxable_id) and taxable_type + taxable_id would be a composite foreign key for each related model with taxable_type having as value the name of the related model (Service or Product in my case) and the taxable_id field the id of the related record of the respective model.
I understand how to make it work with raw queries, but Is there a "Django" way to do that with a ManyToMany relationship? So far I had no luck with that. I don't have much experience with Django, but I hope there is a way to do that without using raw queries.
Help :)
Well, after some thought, I did a better search and stumbled upon django-polymorphic. Here is a pretty straightforward explanation on how it works, for a basic set up and it does what I am describing in my question. The implemented schema differs a bit from what my description, but in the end we will home one intermediate table for all associated models.

How to create an associative entity with extra fields in django

I am facing the following problem.
I have to entities,Proposal and User, a user can vote up or down several proposals and a proposal can have several votes from several users.
This relation between Proposal and User is Many to Many, the thing is that here I want to add an extra field to indicate if the Vote is positive or negative.
Is there are a way to do this in Django using ManyToManyField?, or the only way to do this is creating the model entity of Vote by hand like this:
class Vote(models.Model):
user = models.ForeignKey(User,related_name='voter',null=False)
proposal = models.ForeignKey(Proposal,related_name='vote_to',null=False)
opinion = models.BooleanField(blank=False,null=False)
And in case I have to do it by hand, how I can do for saying to Django that the primary key is the composition of the others Foreign keys
Creating a separate model Vote is a better way to do it, because a vote is specific to a particular proposal for a particular user, so it can't be directly linked to the Proposal model or to the User model.
See this article regarding mutiple column primary keys support in Django, and also this answer.

TYPO3 Extension Builder Foreign Key

Why does the TYPO3 Extension Builder don't generate Foreign keys?
I've set some relations between the models, but in SQL Code there are noe FKs only colums for the Value of the key.
Does anyone can help me?
Cite from Kartsen Dambekalns
It is a half-conscious design decision. Just look up the date when
foreign key constraints where introduced in MySQL, and compare to when
TYPO3 was 'born'.
Of course it would be great to add such references, especially since
MySQL can always handle themm, even if the underlying storage engine
doesn't handle them (in case of which they'll just be ignored).
(source)
Nothing changed till now, so you need to create foreign keys yourself after modeling.
Answer to comment:
how did you handle the relations between two tables? for example I've got a table people which relates to the table house with the column housenr
That depends on relation type of course (1:n, n:1, m:n, etc) and Builder supports creating relations in modeling tool perfectly. Keep in mind, that foreign keys are NOT required for keeping relations in TYPO3.
There are some rules described in TCA section of documentation, i.e. in mentioned case you can use select or group (with internal_type) type of field. For many-to-many relation also you'll need to create MM table. If you'll follow these documents, you can be sure, that in common backend editing form they will be handled properly.
As mentioned before Extension Builder supports creating different types of relations in its click-click modeling tool and it's worthy to spend some time to play with it to see how relations of different types are handled in TYPO3. It uses the same rules that are used in creating relations also in pre-extbase extensions. What's more Builder adds required methods to the models i.e. for getting, attaching and detaching MM objects of given relation field, therefore it's most important to model all your relations at start. In other case you'll need to write these methods manually (which is boring process)

Third-party-app for merging Django user objects?

I need to merge two users in a Django database.
So I wonder if there is any simple way (maybe a dedicated app) to do that?
For example:
We have user_a and user_b and some models that have foreign keys to the User model (Books, Interests, Teams and so on…).
By merging users, I want to delete the object user_b and to set all foreign keys pointing to this object to point to user_a. And – this is my main concern – I want the objects that need to be changed because they reference the to-be-deleted object to be determined automatically without having to specify a list of those Models and foreign key fields in them manually.
Is this already implemented and I'm reinventing the wheel?
Is this possible?
If not, please show me the way to do it: how can I build a list of Django models that have a foreign key to a specific model (User in my case) in runtime?
Thank you for your time.
I found this snippet http://djangosnippets.org/snippets/2283/ . I'm going to have to modify it though, to make it recursive. I will share my code once I'm done.
With Django 1.8 and beyond, you could achieve this robustly using the Model _meta API.
Specifically, you could use Options.get_fields. This will even let you handle generic relations.
You'll need to consider for each related field whether you want to add or replace on merge. This decision depends on your application logic and corresponding schema choices.
u = User.objects.get(pk=123)
related_fields = [
f for f in u._meta.get_fields()
if (f.one_to_many or f.one_to_one)
and not f.concrete
]
for f in related_fields:
# use field's attributes to perform an update

Is there an autoincrement-per-user field in Django?

I was wondering if there is already a way to create a separate autoincrement-ID-per-user field in Django?
Basically, I'm storing many related models and I need the IDs generated to be autoincrement per user.
I don't want to change how id works, just need a new field that I can add which is unique=True per user.
Any suggestions (other than overriding save and implementing it myself)?
No, there's no such field, but I wonder why you think you need it. The ID is really just for the model's internal use, you shouldn't ever care what it is.
For example, if you want to know how many related items there are for a user then you would just use the count() method on the related queryset. If you want something to be unique per user, you can use the unique_together meta property.
Can you given an example of a use case for a per-user unique id?
Edited in response to comments: to get the object from a URL as you mention, you just need to do:
myuser.myobject_set.all()[7]