Using primary key from intermediary model as foreign key in django - django-models

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.

Related

M2M relation Django, with custom intermediate table having an extra field

I have two models like CinicHospital and Doctor with M2M relationship. The custom intermediate table is created because I need an extra field.
class DoctorHospital(models.Model):
clinic = models.ForeignKey(ClinicHospital, on_delete=models.CASCADE)
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
shift = models.CharField(max_length = 10)
Problem in this DoctorHospital model two fields are auto-filled while creating ClinicHospital and Doctor but I'm trouble to fill the shift field.
Could I combine this shift field in doctor form and save it in intermediate table?

How does ForeignKey work in this Django example?

I am having trouble understanding how to use ForeignKey and what exactly it does. Does it link two tables? Or does it link specific columns between each table? Here is a very basic example:
class Seller(models.Model):
name = models.CharField()
email = models.CharField()
zipcode = models.CharField()
class ItemsForSale(models.Model):
item = models.CharField()
description = models.CharField()
zipcode = models.ForeignKey(Seller)
What I'm trying to do is when someone fills out a form to sell an item, I want the zipcode for that item to be automatically set as the sellers zipcode (so the end user won't even have to fill out a zipcode in the form).
Why is it ForeignKey(Seller) instead of ForeignKey(Seller.zipcode)? I guess I don't understand am I linking the entire 'Seller' table? Or just the zipcode column?
Since I don't understand how ForeignKey works, I don't know how to write a view method that sets the zipcode for ItemsForSale. so I really think the key to helping me understand all this would be to see a proper view method that sets the ItemForSale's zipcode to the Sellers zipcode.
In Django a ForeignKey is a relationship between Objects.
In a database a ForeignKey is a field (column) in a table that links to a row of another table.
Visit the django docs and wikipedia for more information about ForeignKeys.
Now to your Django example:
Every single Item (ItemsForSale) has a Seller. (Note: Model names should always be singular.)
So we add a ForeignKey in your ItemsForSale-model that relates to the item's seller:
class ItemsForSale(models.Model):
...
seller = models.ForeignKey(Seller)
Now you can access the item's seller (and of course all of his attributes (including his zipcode) this way:
ItemsForSale.get(item='Foo').seller.zipcode

django model: have recursive relationship

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.

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.

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