How to access ForeignKey-Objects in Django - python

Every user in my Django project has a list of Reports. I now want to display the user his list of reports. But how can I get all receipts which belong to a specific user?
Report-Model
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Report(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=False, null=False)
department = models.CharField(max_length=256, blank=False, null=False)
workshop = models.CharField(max_length=256, blank=False, null=False)
teacher = models.CharField(max_length=256, blank=False, null=False)
hours = models.IntegerField(blank=True, null=False, default=4)
date = models.DateField(blank=True, null=False)

For example, if you want to get the reports of the logged in user you can do the following.
reports = Report.objects.filter(user=request.user)
this should return all the reports of a user. Similarly change the request.user object to another user object and is should work fine as well.
Note - I am assuming "reports" and "receipts" are the same the thing here cause there's no mention of receipt attribute in your model.

Related

django assign User to a model

I want to assign a User to a Model in django, I created a custom User model and sign-up/sign-in Forms but now I want to Assign a User model to another model named Customer whenever a new user is Created Here he the Customer model
class Customer(models.Model):
id = models.AutoField(primary_key=True)
User = models.OneToOneField(
Account, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, default='0', null=True, blank=True)
address = models.CharField(
max_length=200, default=' ', null=True, blank=True)
city = models.CharField(max_length=200, default=' ', null=True, blank=True)
def __str__(self):
if self.name == None:
return "ERROR-CUSTOMER NAME IS NULL"
return self.name
Note: I can assign the User manually in the Database and It lists All the Users but I want it to do it itself when a new user is created
I think it would be better to extend the User model, and add more fields rather than creating a new model (which has a User onetoonefiled in it).
Something like this:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
This is the kind of approach I use in my projects.
Here you have the default User model fields:
User model default fields
You don't need to add these in your Profile class.
I based this on this article: How to extend User Django Model
don't forget to add to the admin.py:
from django.contrib import admin
from .models import Profile
# Register your models here.
admin.site.register(Profile)
to see the Profiles in the admin page
Got it fixed by setting the user in the Customer model when a user is created
Customer.objects.create(user=request.user, name=username, email=email, phone=phone)

Django - get model in navbar

I have a class in models.py :
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
device = models.CharField(max_length=200, null=True, blank=True)
Is there a way to access this model in navbar without creating entry in "views.py"? I would like to access similarly to {{ request.user.id }}.
Customer is related to User using One-to-one relationship, you can get it through User object
request.user.customer
EDIT (after determining Customer and User are not really related):
You can write your own context processor which will return Customer object

create a django user while creating a records for model

models.py as below,
from django.db import models
from django.contrib.auth.models import User
class members(models.Model):
auto_id = models.AutoField(primary_key=True)
member_name = models.OneToOneField(User)
owner = models.ForeignKey('auth.User', related_name='webapi', on_delete=models.CASCADE)
father_name = models.CharField(max_length=25, blank=False, default='')
wife_name = models.CharField(max_length=25, blank=False, default='')
number_of_child = models.IntegerField(blank=True)
address_line_1 = models.CharField(max_length=40, blank=False, default='')
address_line_2 = models.CharField(max_length=40, blank=True, default='')
city = models.CharField(max_length=25, blank=False, default='')
class Meta:
ordering = ('member_name',)
Now The above has been linked with django auth Users table and in steriliser it shows the existing Django users and I have to choose one during the submit.
But my requirement is as a admin user I login and then provide the member_name manually which should automatically create a django user also
django-annoying has a feature for this, specifically AutoOneToOneField.
Sample from their github:
from annoying.fields import AutoOneToOneField
class MyProfile(models.Model):
user = AutoOneToOneField(User, primary_key=True)
This should automatically create a User.

Extending User but still use default Django admin

I am new to programming Django, so I'm not sure if this is possible.
I have created a new CustomUser class:
class CustomUser(AbstractBaseUser):
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
mobile = models.CharField(max_length=30, null=True)
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
date_of_birth = models.DateField(null=True)
Primary_address = models.CharField(max_length=50, null=True)
Primary_address_zipcode = models.CharField(max_length=5, null=True)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
A few questions:
Question 1: I have redefine some of the fields that exists in the default User class (e.g. First Name, Last name, Date Joined). However, I didn't define Last_login. But last_login still shows up as a column in the admin page. But if I don't define First Name, Last Name and Date Joined in my new CustomUser, I get an error and doesn't show up in the admin page. Why is last login special?
Question 2: The default admin page has great UI for group and permission control. Is it possible to define my CustomerUser and still use/enable the default admin page?
Thanks.
you dont need to define all these fields that are already there in django. dont reinvent the wheel. what error are you getting? traceback?
using your customuser model has nothing to do with using default admin page. you can always use django admin page no matter what models you have. Or i dont understand what you really want to achieve.

Using Django ORM to get a related model in a method

Giving the following models...
class ProjectComment(RewardBase):
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
class User (AbstractBaseUser):
email = models.EmailField()
class Profile(models.Model):
bio = models.CharField(max_length=80)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, unique=True)
From project I want to get the Users Profile bio, this is how I'm doing it....
def get_profile_bio(self):
return Profile.objects.get(user=self.user)
I now print a list of all projects I can get a profile bio, but is this the right way to do it? I'm worried that for every project it makes a new SQL call to the DB, is this correct?
class ProjectComment(RewardBase):
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name="projects")
class User (AbstractBaseUser):
email = models.EmailField()
class Profile(models.Model):
bio = models.CharField(max_length=80)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, unique=True, related_name="profile")
Then you can fetch the users and the profiles:
projects = ProjectComment.select_related('user', 'user__profile').exclude(user__isnull=True).all()
for project in projects:
users = [user for user in project.user.all()]
And then:
for user in users:
profiles = [profile for profile in user.profile.all()]
Why do you have a unique constrain in your ForeignKey? if you need Uniquness create a OneToOneField

Categories