I have some unmanaged models to get data from an Oracle database, but I cannot read anything in the documentation about joining tables.
I have these models
class Model1(models.Model):
id = models.CharField(max_length=200, primary_key=True)
name = models.CharField(max_length=200, blank=True, null=True)
class Meta:
managed = False
db_table = 'table_1_name'
class Model2(models.Model):
model1_id = models.CharField(max_length=200, blank=True, null=True)
class Meta:
managed = False
db_table = 'table_2_name'
and I'm trying to join the tables in model 1 and model 2.
I thought I could use model1 = models.ForeignKey(Model1) in Model2 to get data with obj.model1__name, but I cannot make it work.
The problem isn't anything to do with unmanaged models - it's just a question of syntax.
The ForeignKey declaration is correct, but accessing the related information is done via the dot syntax: obj.model1.name.
Related
I'm having an issue with the table names format of my Django project.
Here is a sample of a model I have:
class WalletHistory(models.Model):
wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE, related_name='wallet_history')
free_amount = AmountField(default=None, blank=True, null=True)
locked_amount = AmountField(default=None, blank=True, null=True)
flexible_amount = AmountField(default=None, blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True, blank=True)
The app associated with this model is called core so the table name is supposed to be core_wallet_history. But Django names my table core_wallethistory instead: it doesn't split the class names with underscore.
I've changed nothing in the Django settings.
Sorry I can't post comments yet as I don't have enough reputation.
How are rendering your tables?
I use django-tables2 and all I have to change is the attributes via the class Meta under the table.
Example:
class offer_table(ExportMixin,tables.Table):
offer_name = tables.Column(accessor='offer_name')
class Meta:
attrs = {"name":"offer_table", "id":"offer_table",}
I am trying to create form using this model. I want to add data in this database model using form to perform CRUD operation. I am using MySQL database.
models.py
from django.db import models
from .managers import CategoryManager, SubCategoryManager
# this is my parent model
class Node(models.Model):
name = models.CharField(max_length=150)
parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
related_name='children',
null=True,
blank=True
)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
verbose_name_plural = 'Nodes'
class Category(Node):
object = CategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'Categories'
class SubCategory(Node):
object = SubCategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'SubCategories'
class Product(models.Model):
sub_category = models.ForeignKey(
SubCategory, on_delete=models.CASCADE
)
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
def __str__(self):
return self.name
Try the Imagine smart compiler which allows automatic generating of code + tests for your CRUD APIs and Django models from a very simple config. Amongst other things, it generates code in the correct way to handle foreign key relationships in Django Views. You can also try a demo here imagine.ai/demo
PS: Something like this simple config will generate all the code for the CRUD API along with the tests!
Model Node {
id integer [primary-key]
name string [max-length 150]
}
Model Product {
id integer [primary-key]
name string [max-length 100]
description string [nullable]
}
I have just started with making a similar site to Pinterest and the site has follower/target system that I have barely any understanding of. So far, my models.py code is below:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=45, null=True)
email = models.CharField(max_length=200, null=True)
password = models.CharField(max_length=200)
nickname = models.CharField(max_length=45, null=True)
target = models.ManyToManyField(self, through='Follow')
follower = models.ManyToManyField(self, through='Follow')
class Meta:
db_table = 'users'
class Follow(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='targets')
target = models.ForeignKey(User, on_delete=models.CASCADE, related_name='followers')
class Meta:
db_table = 'follows'
This code was made with reference to another StackOverflow thread
Django models: database design for user and follower
However, I am having trouble understanding how using "related_name='targets' in 'follower' and "related_name='followers'" in 'target' where I can't see any 'targets'(plural) or 'followers'(plural) in other areas of models.py
Should I get rid of that related_name, since there is no such table called "followers" or "targets"? And if you spot major errors in my code or logic, can you tell me? Thanks!
Should I get rid of that related_name, since there is no such table called followers or targets.
There is never a table named followers or targets. The related_name [Django-doc] is a conceptual relation Django makes to the other model (in this case User). It means that for a User object myuser, you can access the Follow objects that refer to that user through target for example with myuser.followers.all(), so:
Follow.objects.filter(target=myuser)
is equivalent to:
myuser.followers.all()
The default of a related_name is modelname_set, so here that would be follow_set. But if you remove both related_names, then that would result in a name conflict, since one can not add two relations follow_set to the User model (and each having a different semantical value).
if you spot major errors in my code or logic, can you tell me?
The problem is that since ManyToManyFields refer to 'self' (it should be 'self' as string literal), it is ambigous what the "source" and what the target will be, furthermore Django will assume that the relation is symmetrical [Django-doc], which is not the case. You should specify what the source and target foreign keys are, you can do that with the through_fields=… parameter [Django-doc]. It furthermore is better to simply define the related_name of the ManyToManyField in reverse, to avoid duplicated logic.
from django.db import models
class User(models.Model):
username = models.CharField(max_length=45, unique=True)
email = models.CharField(max_length=200)
password = models.CharField(max_length=200)
nickname = models.CharField(max_length=45)
follows = models.ManyToManyField(
'self',
through='Follow',
symmetrical=False,
related_name='followed_by',
through_fields=('follower', 'target')
)
class Meta:
db_table = 'users'
class Follow(models.Model):
follower = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='targets'
)
target = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='followers'
)
class Meta:
db_table = 'follows'
Here a User object myuser can thus access myuser.follows.all() to access all the users that they follow, myuser.followed_by.all() is the set of Users that follow myuser. myuser.targets.all() is the set of Follow objects that he is following, and myuser.followers.all() is the set of Follow objects that are following that user.
Assume I am writing an app to change configurations in a machine. I have 3 created tables as below. Machine configuration shows the current state of configurations for our machine. Users can create their tickets and request for changes of the configurations. RequestDetails will be the table to keep the proposed cofigurations plus some extra info such as the name of the requestor, date etc.
These classes are just a simple examples, in the real model I would have nearly 600+ fields=configuration presented in class MachineConfiguration. I should have EXACTLY THE SAME fields in RequestDetails class too. I was wondering there is a way NOT TO REPEAT MYSELF when defining class RequestDetails when it comes to all the fields that exist in MachineConfiguration model?
I want to write it in a way that if I changed anything in MachineConfiguration table, the same change would apply to RequestDetails table too.
Thanks in advance for the help.
class RequestTicket(models.Model):
subject=models.CharField(max_length=50, null=False, blank=False)
description=models.TextField(null=False, blank=True)
class MachineConfiguration(models.Model):
field_1 = models.CharField(null=False,blank=True)
field_2 = models.CharField(null=False, blank=True)
field_3 = models.CharField(null=False, blank=True)
class RequestDetails(models.Model):
tracking_number=models.ForeignKey('RequestTicket')
field_A=models.DateField(null=True, blank=False)
field_B=models.TextField(null=True, blank=False)
field_1 = models.CharField(null=False, blank=True)
field_2 = models.CharField(null=False, blank=True)
field_3 = models.CharField(null=False, blank=True)
Yes you can create the base class and inherit that class in another class like,
class BaseModel(models.Model):
field1 = models.CharField()
field2 = models.CharField()
class Meta:
abstract = True
And inherit this class in another model to get those same field,
# Now if you change any field in BaseModel, it will reflect in both the models
class MachineConfiguration(BaseModel):
pass
class RequestDetails(BaseModel):
field3 = models.CharField()
I am working with some legacy database models in a Django REST Framework application:
class Variable(models.Model):
var_id = models.AutoField(primary_key=True)
resource_type = models.CharField(max_length=1, blank=True, null=True)
resource_id = models.BigIntegerField(blank=True, null=True)
var_name = models.CharField(max_length=500, blank=True, null=True)
class Meta:
managed = False
db_table = 'variables'
class Project(models.Model):
project_id = models.AutoField(primary_key=True)
name = models.CharField(unique=True, max_length=100, blank=True, null=True)
class Meta:
managed = True
db_table = 'projects'
Project and Variable are related models such that when the resource_type of a Variable is 'P', then its resource_id represents the project_id of the Project it belongs to. If the resource_type is something other than 'P, then that Variable belongs to a different type of model. I unfortunately can not make significant changes to the database schema for these models.
Is there a way to define a custom relationship between these two models so that I can treat them as if Variable was defined with a ForeignKey to Project? Or as if Project has a ManyToManyField relationship to Variable? I'd ultimately like to be able to create a nested serializer relationship. Something like:
class Variable(serializers.ModelSerializer):
class Meta:
model = models.Variable
fields = ('var_id', 'resource_type', 'resource_id', 'var_name')
class ProjectSerializer(serializers.ModelSerializer):
variables = VariableSerializer(many=True)
class Meta:
model = models.Project
fields = ('project_id', 'name', 'variables')
Thanks!