django model: have recursive relationship - django-models

How would I correctly model a recursive relationship as the one illustrated below?
class A(models.Model):
previous_A = models.OneToOneField(A)

With Django you can model parent-child relationships as follows:
class Person(models.Model):
name = models.CharField(max_length=128)
parent = models.ForeignKey('self', null=True, related_name='children')
Quoting the ForeignKey docs:
To create a recursive relationship – an object that has a many-to-one
relationship with itself – use models.ForeignKey('self').
P.S. By "reflexive relationship" I assumed you are referring to a recursive association that connects a single class type (serving in one role) to itself (serving in another role); i.e. parent-child relationship.

Related

Using primary key from intermediary model as foreign key in django

I have two models with many to many relationship through an intermediary model. Is it possible to use primary key from the intermediary model as foreignkey in another model?
class Teacher(models.Model):
title = models.CharField(max_length=20)
class Course(models.Model):
title = models.CharField(max_length=20)
teachers = models.ManyToManyField(Teacher, through='Teacher_Course')
class Teacher_Course(models.Model):
teacher = models.ForeignKey(Teacher, on_delete=CASCADE)
course = models.ForeignKey(Course, on_delete=CASCADE)
allotedLectures = models.IntegerField()
class Lecture(models.Model):
teacher_course = models.ForeignKey(Teacher_Course)
content = models.CharField(max_length=255)
Is it valid to use ForeignKey relation in the Lecture model in this way?
Since you have created the through table as a model explicitly it will have a PK, which means that other tables can use that as a FK. TL;DR, yes.

Best way to bypass cakePHP's HABTM auto-magic?

My question is in relation this this answer.
https://stackoverflow.com/a/8773953/1297775
I have read at many places, what #deceze put as:
"To be quite honest, for any halfway complex application, relying on Cake's automagic handling of HABTM relationships can get quite fragile and hard to debug, so I always manage HABTM records myself."
Even the CakePHP book hints at it http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I want to ask, that when he says he 'manages' this HABTM records himself, does he...
1) Not create the HABTM relations in the models at all and create a model for the join table
OR
2) Create the HABTM relations in the models, but does not use it in the controller code by just using $this->FirstModel->JoinModel->saveAll($someData);
Thanks
Basically you need use a hasManyThrough relationship, which is essentially a HABTM setup manually which allows you to add extra data to the relationship (such as created/expiry dates). It's quite simple, you just need to create a model to join them and use the normal belongsTo and hasMany properties in the model, here is a simple user/membership/course setup:
class User extends AppModel {
public $hasMany = array('Membership');
}
class Course extends AppModel {
public $hasMany = array('Membership');
}
class Membership extends AppModel {
public $belongsTo = array('User', 'Course');
}
The only fields (at minimum) the memberships table needs is course_id and user_id.
You can now operate on the Membership model as a normal model, without Cake treating it as HABTM and using its auto-magic whenever you save records. You can also use cool counterCaches on the membership model to count how many users a course has etc.

Creating ManyToMany reference between db.Model and NDB

Changing question. I Want to apply ManyToMany relationship between db.Model and NDB.
example
NDB model
class my_NDB(search.SearchableModel):
.......
.......
db model
class Test(search.SearchableModel):
email = db.StringProperty()
created_by = db.IntegerProperty()
Can I apply ManyToMany relationship between these models?
EDIT:
Here is my User Model
class User(model.Expando):
"""Stores user authentication credentials or authorization ids."""
#: The model used to ensure uniqueness.
unique_model = Unique
#: The model used to store tokens.
token_model = UserToken
created = model.DateTimeProperty(auto_now_add=True)
updated = model.DateTimeProperty(auto_now=True)
# ID for third party authentication, e.g. 'google:username'. UNIQUE.
auth_ids = model.StringProperty(repeated=True)
# Hashed password. Not required because third party authentication
# doesn't use password.
email = model.StringProperty(required=True)
is_active = model.BooleanProperty(required=True)
password = model.StringProperty()
And Here is my Test db model
class Test(search.SearchableModel):
email = db.StringProperty()
created_by = db.IntegerProperty()
Now I want to apply manyToMany on Test. Is it possible?
Django style ManyToMany
created_by = models.ManyToManyField(User)
I see. I had to look up the Django ManyToManyField docs. IIUC you want a Test to be created by multiple users, and of course each user can create multiple tests. Have I got that right?
The way to do this would be to have a db.ListProperty(db.Key) in the Test class, so that the Test class has a list of keys -- where the keys point to User entities.
Now your User model is an NDB class, which complicates matters a bit. However the ndb Key class has an API for converting to and from db Keys:
If you have an ndb Key k, k.to_old_key() returns the corresponding db.Key.
If you have a db Key k, ndb.Key.from_old_key(k) returns the ndb.Key for it (it's a class method).
Hope this helps. Good luck!
PS. Please update your code to use from google.appengine.ext import ndb so you can write ndb.Expando, ndb.StringProperty, etc.

On a database level, what is the difference between [Django] OneToOneFiled and ForeignKey(Model, unique = True)

Both seems to be generating integer NOT NULL UNIQUE REFERENCES databaase columns.
Edit: My question is only about at the database level. (Not in the Django ORM.)
ForeignKey fields should be used for 1 to n relationships and OneToOneField should be used to 1 to 1 relationships.
On database level, the foreign key is unique for OneToOneFields and that's not the case for ForeignKeys.
Your answer is on the official documentation.
Basically, the difference is that when you try to access the ForeignKey from your object, you'll get another object, and not a queryset as you would in the ForeignKey.
From the docs:
class OneToOneField(othermodel[, parent_link=False, **options])
A one-to-one relationship. Conceptually, this is similar to a ForeignKey with unique=True, but the "reverse" side of the relation will directly return a single object.

Use database view in Django

I saw the question can i use a database view as a model in django and tried it in my app, but that didn't work.
I created a view named "vi\_topics" manually and it had "id" column but I kept getting an error, even if I added "id" field explicitly, saying
"no such column: vi_topics.id"
Here is the definition of my model named Vitopic:
from django.db import models
class Vitopic(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author_name = models.CharField(max_length=200)
author_email = models.CharField(max_length=200)
view_count = models.IntegerField(default=0)
replay_count = models.IntegerField(default=0)
tags = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'vi_topics'
Note: I use sqlite3.
Try this:
http://docs.djangoproject.com/en/dev/ref/models/options/#managed
managed
Options.managed
New in Django 1.1: Please, see the release notes
Defaults to True, meaning Django will create the appropriate database tables in syncdb and remove them as part of a reset management command. That is, Django manages the database tables' lifecycles.
If False, no database table creation or deletion operations will be performed for this model. This is useful if the model represents an existing table or a database view that has been created by some other means. This is the only difference when managed is False. All other aspects of model handling are exactly the same as normal. This includes
Adding an automatic primary key field to the model if you don't declare it. To avoid confusion for later code readers, it's recommended to specify all the columns from the database table you are modeling when using unmanaged models.
If a model with managed=False contains a ManyToManyField that points to another unmanaged model, then the intermediate table for the many-to-many join will also not be created. However, a the intermediary table between one managed and one unmanaged model will be created.
If you need to change this default behavior, create the intermediary table as an explicit model (with managed set as needed) and use the ManyToManyField.through attribute to make the relation use your custom model.
For tests involving models with managed=False, it's up to you to ensure the correct tables are created as part of the test setup.
id = models.IntegerField(primary_key=True)

Resources