This my model of first Database DB1:
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=100, null=True)
address = models.TextField(max_length=200, null=True)
website = models.CharField(max_length=200, null=True)
conatct_no = models.CharField(max_length=20, null=True)
email = models.EmailField(max_length=20, null=True)
logo = models.FileField(upload_to='logo/', blank=True, null=True)
created = models.DateTimeField('company created', auto_now_add=True)
updated = models.DateTimeField('company updated', auto_now=True, null=True)
def __unicode__(self): # Python 3: def __str__(self):
return self.name
Model of 2nd Database Db2:
from django.db import models
from leavebuddymaster.models import Company
class Department(models.Model):
company = models.ForeignKey(Company)
department_name = models.CharField(max_length=50, null=True)
created = models.DateTimeField('department created', auto_now_add=True)
updated = models.DateTimeField('department updated', auto_now=True, null=True)
def __unicode__(self): # Python 3: def __str__(self):
return self.department_name
Now when i open the Department table it gives me a error as:
ProgrammingError at /admin/leavebuddyapp/department/
(1146, "Table 'leavebuddy_master.leavebuddyapp_department' doesn't exist")
I have done all the settings in settings.py correctly for the two databases. Can you please guide me in the right direction. Thanx in advance.
You're correct, Django does not currently support foreign key relationships spanning multiple databases.
From Cross-database relations [Edit 2020: Django version bump]:
If you have used a router to partition models to different databases, any foreign key and many-to-many relationships defined by those models must be internal to a single database.
This is because of referential integrity. In order to maintain a relationship between two objects, Django needs to know that the primary key of the related object is valid. If the primary key is stored on a separate database, it’s not possible to easily evaluate the validity of a primary key.
A solution I thought up that you could try (though it may present other problems):
from leavebuddymaster.models import Company
class Department(models.Model):
company_id = models.IntegerField()
#property
def company(self):
return Company.objects.get(pk=self.company_id)
This allows you to refer to Department.company like you normally would in your example. Setting it would just be a matter of Department.company_id = Company.pk. Hope it helps, or at least inspires a better solution!
Related
I am using Django Rest Framework and I have this query in raw SQL but I want to do it in the Django ORM instead.
I have tried using the different Django tools but so far it has not given me the expected result.
select tt.id, tt.team_id, tt.team_role_id, tt.user_id from task_teammember tt
inner join task_projectteam tp on tp.team_id = tt.team_id
where tp.project_id = 1
models
class TeamMember(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
team_role = models.ForeignKey(TeamRole,on_delete=models.CASCADE)
state = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=None, null=True)
class ProjectTeam(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE, blank=True, null=True)
team = models.ForeignKey(Team, on_delete=models.CASCADE, blank=True, null=True)
state = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=None, null=True)
If you have a project object already then this should get you what I believe you want. Your TeamMember model has access to Team, which links to ProjectTeam, and to Project - the double-underscore accessor navigates through the relationships.
TeamMember.objects.filter(team__projectteam__project=project)
I would advise to span a ManyToManyField over the ProjectTeam, this will make queries simpler:
from django.conf import settings
class TeamMember(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now=True)
# …
class Team(models.Model):
projects = models.ManyToManyField(Project, through='ProjectTeam')
# …
class ProjectTeam(models.Model):
# …
updated_at = models.DateTimeField(auto_now=True)
Then you can easily filter with:
TeamMember.objects.filter(team__projects=project_id)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Django's DateTimeField [Django-doc]
has a auto_now=… parameter [Django-doc]
to work with timestamps. This will automatically assign the current datetime
when updating the object, and mark it as non-editable (editable=False), such
that it does not appear in ModelForms by default.
I think it's goes like:
TeamMember.objects.filter(team__projectteam__project__id=1)
Django orm allow reverse foreginkey lookup
In My Django Project, there are two apps: Login and Company
The error that am receiving in this is
AttributeError: module 'login.models' has no attribute 'Country'
Company App > models.py
from django.db import models
from login import models as LM
class CompanyProfile(models.Model):
full_name = models.CharField(max_length=255,
unique = True)
country = models.ForeignKey(LM.Country,
on_delete=models.SET_NULL,
null=True,
blank=False)
state = models.ForeignKey(LM.State,
on_delete=models.SET_NULL,
null=True,
blank=False)
def __str__(self):
return self.full_name
Login App > models.py
class Country(models.Model):
"""List of Country"""
name = models.CharField(max_length=50, unique= True, default='None')
code = models.CharField(max_length=2, unique= True, primary_key=True, default ='NA')
def __str__(self):
return str(self.code)
class State(models.Model):
"""List fo State"""
region = models.CharField(max_length = 255, unique = True, primary_key=True, default='None')
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, blank=False, default ='NA')
def __str__(self):
return self.region
Here is test to check that weather is login is getting imported or not
def test_import():
try:
# import pdb; pdb.set_trace()
importlib.find_loader('LM.Country')
found = True
except ImportError:
found = False
print(found)
Answer is received stands to be True
python3 manage.py shell
>>> test_import()
True
Now on other stackoverflow blogs i checked i thought it could be of Circlular Import
But i have already fixed that still am getting this error?
Thanks in Advance
Regards
I am not able to see any issue here technically. Maybe Django doesn't support this alias way of mentioning model as Foreign Key which I have never tried this way.
But I would suggest to use string format for adding Foreign Key of other model as below.
class CompanyProfile(models.Model):
full_name = models.CharField(max_length=255, unique = True)
# In following line, as I mention model name in string which django understands
country = models.ForeignKey('login.Country', on_delete=models.SET_NULL,
null=True,blank=False)
Another way is simple import but it might be a problem in case of circular depedencies. So I don't recommend to use that.
I hope you get the answer out of it.
I'm writing a django migration operation to change some data in the 'default' database. My app has access to a 'services' database, which contains data I cannot change.
The two relevant fields in the default.table are:
data_sets_to_remove = models.CharField(blank=True, null=False, max_length=100, default="")
data_sets_new = ArrayField(models.IntegerField(null=True, blank=True), null=True, blank=True)
i.e., i'm migrating data from data_sets_to_remove into a new format and adding to data_sets_new. To do this, I need to access data from the 'services' database in the migration operation.
def forwards_func(apps, schema_editor):
DataRelease = apps.get_model('registry', "datarelease")
Survey = apps.get_model('registry', "survey")
data_release_queryset = DataRelease.objects.using('services').all().values('id', 'name', 'survey')
But for some reason, the foreign key field 'survey' on the DataRelease model is not available in this context.
django.core.exceptions.FieldError: Cannot resolve keyword 'survey'
into field. Choices are: id, name
Can anyone shed any light on this? I assume the issue is around accessing data from a secondary database within a migration operation, but if i run the same code in the console, it works fine...
The relevant Survey and DataRelease models in the services database:
class Survey(models.Model):
name = models.CharField(blank=False, null=False, max_length=100, unique=True)
class DataRelease(models.Model):
name = models.CharField(blank=False, null=False, max_length=100)
survey = models.ForeignKey(Survey, related_name='data_releases', on_delete=models.CASCADE)
:facepalm:
The answer was staring me in the face. Switched the import of the associated models from:
DataRelease = apps.get_model('registry', "datarelease")
Survey = apps.get_model('registry', "survey")
to:
from services.registry.models import DataRelease, Survey
Now I can access the related fields in the migration operation. Hopefully this helps someone else in the future!
I am trying to query from backward: at fist see my models:
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=100, unique=True)
body = models.TextField()
category = models.ForeignKey('blog.Category', on_delete=models.CASCADE)
def __unicode__(self):
return '%s' % self.title
class Category(models.Model):
name = models.CharField(max_length=100, db_index=True)
I have many category and many post, one category name is tech I am trying to get all the post those are in tech category.
I tried like this. Category.objects.filter(contain__exact='tech') but it is not work anymore.
Can anyone help me to figure get it done?
Best way to get all the post in tech category using foreign key.
tech_blogs = Blog.objects.filter(category__name__icontains='tech')
and also change
category = models.ForeignKey('Category', on_delete=models.CASCADE)
I have a Django app that works perfectly on google app engine, using the datastore via djangae. However, the admin site throws an error:
NotSupportedError at /admin/auth/user/5629499534213120/change/
Cross-join where filters are not supported on the Datastore
This error only occurs when trying to edit the default Django user model. Not sure why this is happening.
I have used the default Django user model. (this is an app dealing with donations for a nonprofit)
models.py:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class FoodSplashUser(models.Model):
base_user = models.OneToOneField(User, on_delete=models.CASCADE)
address = models.TextField(null=True)
city = models.TextField(null=True)
state = models.CharField(max_length=4, null=True)
zip = models.CharField(max_length=10, null=True)
def __str__(self):
return str(self.base_user.username)
class Organization(models.Model):
base_user = models.OneToOneField(User, on_delete=models.CASCADE)
address = models.TextField(null=True)
city = models.TextField(null=True)
state = models.CharField(max_length=4, null=True)
zip = models.CharField(max_length=10, null=True)
description = models.TextField(null=True)
image_url = models.URLField(null=True)
def __str__(self):
return str(self.base_user.username)
class DonationRequest(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now=True)
request_type = models.TextField(null=True)
description = models.TextField(null=True)
def __str__(self):
return str(self.organization.base_user.username) + " " + self.request_type
class DonationPromise(models.Model):
user = models.ForeignKey(FoodSplashUser, on_delete=models.CASCADE)
donation_request = models.ForeignKey(DonationRequest, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now=True)
verified = models.BooleanField(default=False)
def __str__(self):
return str(self.user.base_user.username) + " " + str(self.donation_request)
This app goes with the default Django admin interface, but I decided to make the classes below for easy editing later.
admin.py:
from django.contrib import admin
from . import models
# Register your models here.
class FoodSplashUserAdmin(admin.ModelAdmin):
pass
class OrganizationAdmin(admin.ModelAdmin):
pass
class DonationRequestAdmin(admin.ModelAdmin):
pass
class DonationPromiseAdmin(admin.ModelAdmin):
pass
admin.site.register(models.FoodSplashUser, FoodSplashUserAdmin)
admin.site.register(models.Organization, OrganizationAdmin)
admin.site.register(models.DonationRequest, DonationPromiseAdmin)
admin.site.register(models.DonationPromise, DonationPromiseAdmin)
This may be a separate error, but :
admin.site.register(models.DonationRequest, DonationPromiseAdmin)
admin.site.register(models.DonationPromise, DonationPromiseAdmin)
Shouldn't that first one be: DonationRequestAdmin?
NotSupportedError indicates that your code performs an action that is not possible with App Engine Datastore. Not all the Django ORM features can be used in a non-relational database which Datastore is. You are trying to create an entity that has some relations, which causes the error. Probably it is a good idea to use Gauth for authentication and user management, as described in the Djangae docs.