I am new to Django and I need data from two models and would like to do it with one query. Here is what I have in sql that gives me exactly what I need. Can someone please show me how to do it in Django.
select api_userprofile.last_name, api_userprofile.first_name,
api_userdevice.is_admin,
api_userdevice.is_alerts_enabled,api_userdevice.is_owner from
api_userprofile
join api_userdevice on api_userdevice.user_id=api_userprofile.user_id
where api_userdevice.user_id=10 and api_userdevice.device_id=29
These are my 2 models:
class UserDevice(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=False)
device = models.ForeignKey(Device, on_delete=models.PROTECT, null=False)
activation_date = models.DateTimeField(default=timezone.now, null=False)
friendly_name = models.CharField(max_length=20, null=True, blank=True)
is_owner = models.BooleanField(null=False, default=False)
is_admin = models.BooleanField(null=False, default=True)
is_alerts_enabled = models.BooleanField(null=False, default=True)
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=False)
token = models.TextField(null=False, blank=True)
first_name = models.TextField(null=True, blank=True)
last_name = models.TextField(null=True, blank=True)
Any help would be greatly appreciated.
There is easy way to do that:
User.objects.filter(userdevice__id=29, id=10).values('userdevice__is_owner', 'userdevice__is_admin', 'userdevice__is_alerts_enabled', 'userprofile__first_name', 'userprofile__last_name')
Related
models:
class FullNameMixin(models.Model):
name_id = models.BigAutoField(primary_key = True, unique=False, default=None, blank=True)
first_name = models.CharField(max_length=255, default=None, null=True)
last_name = models.CharField(max_length=255, default=None, null=True)
class Meta:
abstract = True
class Meta:
db_table = 'fullname'
class User(FullNameMixin):
id = models.BigAutoField(primary_key = True)
username = models.CharField(max_length=255, unique=True)
email = models.CharField(max_length=255, unique=True)
token = models.CharField(max_length=255, unique=True, null=True, blank=True)
password = models.CharField(max_length=255)
role = models.IntegerField(default=1)
verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
def __str__(self):
return self.username
class Meta:
db_table = 'cga_user'
class Profile(FullNameMixin):
id = models.BigAutoField(primary_key = True)
birthday = models.DateTimeField(null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
postcode = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=255, null=True, blank=True)
profession_headline = models.CharField(max_length=255, null=True, blank=True)
image = models.ImageField(upload_to=get_upload_path, null=True, blank=True)
profile_banner = models.ImageField(upload_to=get_upload_path_banner, null=True, blank=True)
cga_user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE, related_name="profile")
gender = models.CharField(
max_length=255, blank=True, default="", choices=USER_GENDER_CHOICES
)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
class Meta:
db_table = 'profile'
When i am creating Profile from django admin panel getting below error.
e
filename = self.upload_to(instance, filename)
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/api/model_utils/utils.py", line 7, in get_upload_path
instance.user,
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/env/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 421, in __get__
raise self.RelatedObjectDoesNotExist(
api.models.FullNameMixin.user.RelatedObjectDoesNotExist: Profile has no user.
[24/Jul/2021 13:49:51] "POST /admin/api/profile/add/ HTTP/1.1" 500 199997
please take a look how can i fix this.
Note: User model creation working but, profile not working
I checked in drf and django admin panel .
both place not working.
The problem here is that you are declaring a User model which is in fact just a model. That's not how it works.
The User is a special type of model and if you want to change it you have to extend the AbstractUser class.
Alternatively you can connect to it via one-to-one classes in the classic user-profiles approach.
But here you are creating a user model that (besides using the reserved word 'User') has none of the requirements necessary to be treated as a user who can be authenticated and that can instantiate sessions.
> Example of a simple user-profiles architecture
> Working with User objects - Django Docs (i particularly recommend this one)
I would recommend you to read-up on django user authentication.
I can use some help on a query using 3 tables. Here is what my models contains.
class VolunteerRecord(models.Model):
eventname = models.CharField(help_text=_('Name of the event'),max_length=256, blank=False, default='')
category = models.CharField(max_length=256, blank=False, choices=CATEGORY_CHOICES)
hours = models.FloatField(blank=False)
date=models.DateField(help_text=_('Enter the date of the event'),validators=MaxValueValidator(limit_value=date.today)])
mileage = models.FloatField(blank=True, null=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
streetaddress1 = models.CharField(blank=True, max_length=256)
streetaddress2 = models.CharField(blank=True, max_length=256)
city = models.CharField(blank=True, max_length=30)
state = models.CharField(max_length=256, blank=False, choices=US_STATES)
zipcode = models.CharField(blank=True, max_length=15)
county = models.CharField(max_length=256, blank=False, choices=STATE_COUNTIES)
I would like to filter all VolunteerRecords where the owner's county = request.user's county
So far I have... (not sure what I am suppose to put where my ??? are)
def history(request):
current_user_county = request.user.profile.county
records = VolunteerRecord.objects.filter(????=current_user_county)
I was able to figure it our with your help.
records = VolunteerRecord.objects.filter(owner__profile__county=request.user.profile.county)
I have a CustomUser model, and a Blog model.
CustomUser model:
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=20, default="", blank=True)
last_name = models.CharField(max_length=20, default="", blank=True)
address = models.CharField(max_length=150, default="", blank=True)
city = models.CharField(max_length=20, default="", blank=True)
zip_code = models.CharField(max_length=20, default="", blank=True)
country = models.CharField( max_length=50, default="", blank=True, choices=settings.COUNTRIES_LIST)
about_me = models.TextField(max_length=225, default="", blank=True)
photo_url = models.TextField(null=True)
is_active = models.BooleanField(default=True) # can login
Blog model:
class Blog(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, verbose_name=_('user'), related_name="%(class)s_blogs", on_delete=models.SET_NULL)
blog_id = models.CharField(max_length=150, null=False, default=get_id, unique=True, editable=False)
blog_title = models.CharField(max_length=150, null=False)
blog_description = models.TextField(max_length=300, null=True, blank=True)
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
blog = FroalaField()
dynamic_link = models.CharField(max_length=225, null=False, default="")
blog_type = models.CharField( max_length=50, null=False, choices=BLOGSTYPE_LIST)
blog_status = models.CharField(max_length=150, null=False, default="unapproved")
is_active = models.BooleanField(default=False)
is_featured = models.BooleanField(default=False)
My understanding is that I could use the related_name to get all blogs by a user.
>>> from users.models import CustomerUser
>>> user = CustomUser.objects.get(pk=1)
>>> user.blog_blogs.all()
<BlogQuerySet []>
As you must have seen, this turns to always return but an empty queryset, even though there are blog entries by that user.
So is it am not understanding here?
Thank you.
My models look like this:
class UserDevice(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=False)
device = models.ForeignKey(Device, on_delete=models.PROTECT, null=False)
activation_date = models.DateTimeField(default=timezone.now, null=False)
friendly_name = models.CharField(max_length=20, null=True, blank=True)
is_owner = models.BooleanField(null=False, default=False)
is_admin = models.BooleanField(null=False, default=True)
is_alerts_enabled = models.BooleanField(null=False, default=True)
timeStamp = models.DateTimeField(auto_now = True, null=False)
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=False)
token = models.TextField(null=False, blank=True)
first_name = models.TextField(null=True, blank=True)
last_name = models.TextField(null=True, blank=True)
timeStamp = models.DateTimeField(auto_now = True, null=False)
I need to get device, user, is_alerts_enabled, is_admin, is_owner from UserDevice and first_name, last_name, token from userProfile. This is what I have so far and it gives me what I need from userdevice but I can't figure out how to add the userprofile stuff.
nonOwners = UserDevice.objects.filter(device=device, is_owner=False)
if nonOwners is None:
return errormsg('non nonOwners found for this device')
nonOwnersArray=[]
for nonOwner in nonOwners:
nonOwner_data = model_to_dict(nonOwner,
fieldlist=(
'device.serial',
'user.email',
'is_alerts_enabled',
'is_admin',
'is_owner',
),
rename={
'device.serial': 'serial',
'user.email': 'email'})
nonOwnersArray.append(nonOwner_data)
Any help would be greatly appreciated. Thanks!
The best way to get a dictionary of values is to use values().
UserDevice.objects.filter(device=device, is_owner=False).values('device', 'user', 'is_alerts_enabled', 'is_admin', 'is_owner')
The above line will give you the relevant fields of the UserDevice model as dictionary values.
If you add a foreign key to UserDevice (here I have changed the user field):
class UserDevice(models.Model):
user = models.ForeignKey(UserProfile, on_delete=models.PROTECT, null=False)
device = models.ForeignKey(Device, on_delete=models.PROTECT, null=False)
activation_date = models.DateTimeField(default=timezone.now, null=False)
friendly_name = models.CharField(max_length=20, null=True, blank=True)
is_owner = models.BooleanField(null=False, default=False)
is_admin = models.BooleanField(null=False, default=True)
is_alerts_enabled = models.BooleanField(null=False, default=True)
timeStamp = models.DateTimeField(auto_now = True, null=False)
You may do this:
UserDevice.objects.select_related('user').filter(device=device, is_owner=False).values('device', 'user', 'is_alerts_enabled', 'is_admin', 'is_owner', 'user__first_name', 'user__last_name', 'user__token')
I have used select_related() to avoid hitting the database unnecessarily.
I am new to django and need to do a query. I can do in sql but I can't seem to figure it out in django. Here it is in SQL. Can someone tell me how to do it in django.
select token from api_userprofile
join api_userdevice on api_userdevice.user_id=api_userprofile.user_id
join api_device on api_device.id=api_userdevice.device_id
where api_device.serial=3
My models look like this:
class UserDevice(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=False)
device = models.ForeignKey(Device, on_delete=models.PROTECT, null=False)
activation_date = models.DateTimeField(default=timezone.now, null=False)
friendly_name = models.CharField(max_length=20, null=True, blank=True)
is_owner = models.BooleanField(null=False, default=False)
is_admin = models.BooleanField(null=False, default=True)
class Device(models.Model):
serial = models.CharField(max_length=16, null=False, unique=True)
publickey = models.CharField(max_length=44, null=False)
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.PROTECT, null=False)
token = models.TextField(null=False, blank=True)
if i understand correctly, you can try:
users_pks = UserDevice.objects.filter(device__serial=3).values_list('user__pk')
qs = UserProfile.objects.filter(user__pk__in=users_pks).values('token')
for check sql query, you can print:
print (qs.query)