I am beginner for Django and i am working on my final year project but i am stuck at one thing.
here is my model.py
class MatchList(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="user")
matches = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name="matches")
class Meta:
app_label = "matchsystem"
Also my here is my migration file as well.
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='MatchRequest',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_active', models.BooleanField(default=True)),
('times_tamp', models.DateTimeField(auto_now_add=True)),
('receiver', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='receiver', to=settings.AUTH_USER_MODEL)),
('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='MatchList',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('matches', models.ManyToManyField(blank=True, related_name='matches', to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
],
),
]
but when i migrate the data it create an extra table with added name.
Any response is much appricated.
Nothing is wrong. In database terms a ManyToManyField is just an extra intermediate table which has foreign keys to the two related tables. This is because you really cannot have multiple values in the same column pointing to multiple entries.
Your first table matchsystem_matchlist you show in the image has the fields id and user_id which is correct, id is the primary key and user_id is the foreign key (in your model user). This is the table for your model MatchList.
Next your second table matchsystem_matchlist_matches has the fields id which is the primary key, matchlist_id which is the foreign key to MatchList and users_id which is the foreign key to the user model. This second table is the intermediate table made for the ManyToManyField named matches in your model MatchList.
Related
Mysql User table: user_id int (pk), name varchar, last_name varchar
SQLAlchemy model:
class User(db.Model):
__tablename__ = 'user'
user_id = Column('user_id',INTEGER, nullable=False, primary_key=True)
name = Column('name',String(256), nullable=False)
lastname = Column('last_name',String(256), nullable=False)
If I want to add columns in my User table like phone_number and address which are not going to be used by my application. Do I need to change necessary my model of sqlalchemy or is it not harmful?
You do not have add the columns into your User class. But if you add data into the database using sqlachemy, it will construct the rows using only the fields from the class User, so if you do not have the defaults set in the database table definition, it may cause an error.
EDIT: You should be safe if you only use the model to query the database.
Currently i have the following model that i would like to set CharField as primary key( my database is Mysql)
class Customer(models.Model):
class Meta:
db_table = "customers"
verbose_name = _('Customer')
verbose_name_plural = _('Customers')
customer_id = models.CharField(_('Customer ID'),max_length=255, primary_key=True)
name = models.CharField(_('Name'), max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
In the document it stated that :
primary_key=True implies null=False and unique=True. Only one primary
key is allowed on an object.
In Mysql the primary key has the following structure:
customer_id, type=varchar(255), collation=latin1_swedish_ci,
Attributes=blank Null=No, Default=None,Comments=blank, Extra=blank
but when i try to use the save() method with null value for primary key:
Customer.objects.create(customer_id=None, name="abc")
It still save Null value in the primary key without returning any error or validation, why is that?
EDIT:
After saving in Mysql it show the value of the customer_id=blank(when try to save it as None). Why it set to blank when saving customer_id=None?
When you create object for the first time
Customer.objects.create(customer_id=None, name="abc")
It will store customer_id value as '' (empty value, not null) and there are no other object we have created till now, so it's unique too.
Now when you again create an Customer object
Customer.objects.create(customer_id=None, name="xyz")
This will throw an error django.db.utils.IntegrityError: UNIQUE constraint failed: customers.customer_id because we already have empty value in our customer_id value. So, this is throwing an error of UNIQUE constraint
Do you use Django Rest Framework?
Then you may have add your customer_id to the read_only_fields in serializer.py
The result is:
You can't add an id in your request
Django doesn't recognised it as a required field anymore (except of Django Admin)
Django accepts a NULL value, which shouldn't be allowed
I'm not sure I've titled this question correctly. I can add a unique constraint well enough to any of my tables, but in the case below I'm not sure how to do what I'm after:
class Branch(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(160))
#foreign key for 'branches' in Account class. access with Branch.account
account_id = db.Column(db.Integer, db.ForeignKey('account.id'))
class Account(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(160), unique=True)
branches = db.relationship('Branch', backref = 'account', lazy = 'dynamic')
So when I added a unique constraint to the Branch table's name column, I could not add same-name branches to different accounts. For example, Seattle, could be a branch for both AccountA and AccountB.
What I want to do is apply a constraint that checks for uniqueness only when account.id is the same. Is this possible?
Thanks to dirn, pointing out the duplicate, I've added:
__table_args__ = (db.UniqueConstraint('account_id', 'name', name='_account_branch_uc'),
)
to my Branch class, and then pushed it to the database with alembic via:
def upgrade():
op.create_unique_constraint('_account_branch_uc', 'branch', ['name','account_id'])
I will note, though, that since I added this constraint manually via alebmic, I'm not certain if I added it correctly to my model. I suppose I'll find out when I eventually wipe my DB and start a new one.
EDIT
I have rolled a new database and the __table_args__ from above works correctly!
I am trying to generate a report across 2 models/ tables. Here they are:
class Members(models.Model):
username = models.CharField(max_length=30,null=True, unique=True)
email = models.CharField(max_length=100,null=True, unique=True)
name = models.CharField(max_length=30,null=True)
phone = models.CharField(max_length=30,null=True)
and
class Report(models.Model):
report_text = models.CharField(max_length=500)
reporter_id = models.IntegerField(db_index=True)
reported_id = models.IntegerField(db_index=True)
date_created = models.DateTimeField(null=True)
date_read = models.DateTimeField(null=True)
The 2 tables obviously have auto increment IDs as the primary key.
The report will look like this:
Reported Phone | Reported Name | Report | Date Reported | Date Report Read
Everyone reported on will be in the member table. The reporter ID is the ID of the member who logged the report. The reported_id is the ID of the person the report is on. I need to do a join across the 2 models to get the members name and their phone number. I can't quite work it out form the doc. I believe I should make the reported_id and reporter_id both foreign keys to the Members table primary key ID field. How do I do that and what code will extract the report for all entries submitted by a specific reporter?
Do I user reported_id = models.ForeignKey(Members) and do the same for reporter_id. It seems odd as I don't specify the field that the field is foreign to. The ORM is supposed to make it easier (and it usually does!). I could do it with a join in SQL but this has got me stumped.
I hope the question makes sense.
Thanks in advance
Rich
How do I do that and what code will
extract the report for all entries
submitted by a specific reporter?
Yes, do reported_id = models.ForeignKey(Members)
The field will be the target models primary key, which is in your case id since you haven't specified one.
You will need to specify a related_name for one of these fields to prevent a name clash for the reverse foreign key accessor.
After setting up the foreign key field, to get all objects related via that foreign key, use the related_name to query the related model.
http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
For example, if you set up your model as:
reporter = models.ForeignKey(Members, related_name="reports_by_me")
reported = models.ForeignKey(Members, related_name="reports_by_others")
You could access all related Report models via that foreign key by
member_instance.reports_by_me.all()
member_instance.reports_by_others.all()
I have the following data:
CREATE TABLE `groups` (
`bookID` INT NOT NULL,
`groupID` INT NOT NULL,
PRIMARY KEY(`bookID`),
KEY( `groupID`)
);
and a book table which basically has books( bookID, name, ... ), but WITHOUT groupID. There is no way for me to determine what the groupID is at the time of the insert for books.
I want to do this in sqlalchemy. Hence I tried mapping Book to the books joined with groups on book.bookID=groups.bookID.
I made the following:
tb_groups = Table( 'groups', metadata,
Column('bookID', Integer, ForeignKey('books.bookID'), primary_key=True ),
Column('groupID', Integer),
)
tb_books = Table( 'books', metadata,
Column('bookID', Integer, primary_key=True),
tb_joinedBookGroup = sql.join( tb_books, tb_groups, \
tb_books.c.bookID == tb_groups.c.bookID)
and defined the following mapper:
mapper( Group, tb_groups, properties={
'books': relation(Book, backref='group')
})
mapper( Book, tb_joinedBookGroup )
...
However, when I execute this piece of code, I realized that each book object has a field groups, which is a list, and each group object has books field which is a singular assigment. I think my definition here must have been causing sqlalchemy to be confused about the many-to-one vs one-to-many relationship.
Can someone help me sort this out?
My desired goal is:
g.books = [b, b, b, .. ]
book.group = g
where g is an instance of group, and b is an instance of book.
Pass userlist=False to relation() to say that property should represent scalar value, not collection. This will for independent on whether there is primary key for this column, but you probably want to define unique constraint anyway.