Why does the following print(owner) return a different value that what's in my model? Is it possible to get the formattedusername defined below? I've simplified my def profile(request) and took out my other arguments till I can figure out the solution to getting formattedusername.
def profile(request):
owner = User.objects.get (formattedusername=request.user.formattedusername)
args = {'user':request.user.formattedusername}
print (owner)
return render(request, 'accounts/profile.html', args)
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
#3-alphas4numeric
[06/Nov/2017 16:18:11] "GET /account/profile/ HTTP/1.1" 200 1416
formattedusername in my model is stored in the database as HCA\3-alphas4numeric, it's also defined by the following, it's also the key field in all my other models and there isn't a way around using an integer for the key since it's a pre-existing database:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=7, unique=True)
formattedusername = models.CharField(max_length=11, unique=True, primary_key = True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=140)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
facility = models.CharField(max_length=140)
jobdescription = models.CharField(max_length=140)
positiondescription = models.CharField(max_length=140)
coid = models.CharField(max_length=5)
streetaddress = models.CharField(max_length=140)
USERNAME_FIELD = 'username'
class Meta:
app_label = 'accounts'
db_table = "user"
def save(self, *args, **kwargs):
self.formattedusername = '{domain}\{username}'.format(
domain='HCA', username=self.username)
super(User, self).save(*args, **kwargs);
When you do print(owner), you will print out the value of USERNAME_FIELD. That's how AbstractBaseUser.__str__ is implemented.
def get_username(self):
"Return the identifying username for this User"
return getattr(self, self.USERNAME_FIELD)
def __str__(self):
return self.get_username()
Related
I am trying to get a list of all pathologists in my system. I need to filter the user on 2 basis i-e is_pathologist and Lab_Id=request.data[email]
I have tried switching between filter and get but then I get
Authentication.models.User.MultipleObjectsReturned: get() returned more than one User -- it returned 12!
Error traceback here
This is the code of my view
#api_view(['POST'])
def getAllPathologists(request):
user = get_user_model().objects.get(is_pathologist=True)
# If user exists, get the employee
print("user is: ", user)
pathologist = Employee.objects.get(user=user.email, Lab_Id=request.data['email'])
pathologistSerializer = EmployeeSerializer(pathologist, many=True)
return Response(pathologistSerializer.data)
This is user model
class User(AbstractUser):
# Add additional fields here
id = None
email = models.EmailField(max_length=254, primary_key=True)
name = models.CharField(max_length=100)
password = models.CharField(max_length=100)
contact_number = models.CharField(max_length=100)
is_patient = models.BooleanField(default=False)
is_doctor = models.BooleanField(default=False)
is_homesampler = models.BooleanField(default=False)
is_pathologist = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_lab = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now=True,editable=False)
last_login = models.DateTimeField(auto_now=True)
first_name = None
last_name = None
username = None
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'password']
objects = CustomUserManager()
def __str__(self):
return self.email
# Ensure that the password is hashed before saving it to the database
def save(self, *args, **kwargs):
self.password = make_password(self.password)
super(User, self).save(*args, **kwargs)
def has_perm(self, perm, obj=None):
return self.is_superuser
This is Employee model
class Employee(models.Model):
user = models.OneToOneField(
get_user_model(), on_delete=models.CASCADE, primary_key=True)
CNIC = models.CharField(max_length=100, unique=True)
Lab_Id = models.ForeignKey(Lab, on_delete=models.CASCADE)
def __str__(self):
return self.user.name
This is employee serializer
class EmployeeSerializer(serializers.ModelSerializer):
userData = UserSerializer(read_only=True, source='user')
email = serializers.EmailField(write_only=True)
password = serializers.CharField(write_only=True)
name = serializers.CharField(write_only=True)
contact_number = serializers.CharField(write_only=True)
is_homesampler = serializers.BooleanField(write_only=True)
class Meta:
model = Employee
# fields = " __all__"
fields = ["CNIC", "Lab_Id", "userData",
"name", "contact_number", "email", "password", "is_homesampler"]
def create(self, validated_data):
print("validated data = ", validated_data)
email = validated_data.pop("email")
password = validated_data.pop("password")
name = validated_data.pop("name")
contact_number = validated_data.pop("contact_number")
is_homesampler = validated_data.pop("is_homesampler")
user = get_user_model().objects.create_user(
email=email, password=password, name=name, contact_number=contact_number)
if (is_homesampler):
user.is_homesampler = True
else:
user.is_pathologist = True
user.save()
EmployeeObj = Employee.objects.create(user=user, **validated_data)
return EmployeeObj
You are getting objects and querysets conflated, filter() will return a queryset whereas get() tries to return an object. Below are the reasons for your errors:
The reason for your error with filter() is that a queryset is essentially a group of user objects. The queryset itself has no attribute email, but each user object within the group would. You therefore need to extract a single user from the queryset using first() or last(), for example.
Your error with get() is that your parameters are too broad and thus 12 users are returned. You need to adjust your code to handle this, it's usually done with either a try/except block or using the get_object_or_404 Django shortcut. Once you successfully get the user object, you can call user.email without issue.
i tried to adding username=None didnt work
Account model is for auth
other models that are diffrent languge are just profile pic or date joined nothing important to the error i imagine
models.py
class Account(AbstractBaseUser):
email= models.EmailField(verbose_name='ایمیل', max_length=60, unique=True)
username = models.CharField(max_length=255, unique=True)
مسکن = models.CharField(max_length=255)
تاریخ_ثبت_نام = models.DateTimeField(verbose_name='تاریخ_ثبت_نام', auto_now_add=True)
اخرین_ورود = models.DateTimeField(verbose_name='اخرین_ورود', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
عکس_پروفایل = models.ImageField(max_length=255 ,upload_to=get_profile_image_filepath,null=True ,blank=True, default=get_default_profile_image)
objects = MyAccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.username
def get_profile_image_filenames(self):
return str(self.عکس_پروفایل)[str(self.عکس_پروفایل).index(f'uploads/{self.pk})/'):]
def has_perm(self,perm, obj=None):
return self.is_admin
def has_module_perm(self , applabel):
return True
I want to check that the card number is exists and then get the associated user to that card number. A user can have multiple card numbers. How do I filter to get the user from the card number entered?
Models:
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(
verbose_name="Email Field", max_length=60, unique=True)
dateJoined = models.DateTimeField(
verbose_name="Date Joined", auto_now_add=True)
last_login = models.DateTimeField(verbose_name="Last Login", auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_verified = models.BooleanField(default=False)
# Parameters that we want to know about the user
first_name = models.CharField(verbose_name="First Name", max_length=100)
last_name = models.CharField(verbose_name="Lasst Name", max_length=100)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
objects = CustomUserManager()
def __str__(self):
return self.email
def tokens(self):
refresh = RefreshToken.for_user(self)
return {
'refresh': str(refresh),
'access': str(refresh.access_token)
}
def has_perm(self, perm, obj=None):
return self.is_superuser
def has_module_pers(self, app_label):
return True
class cardModel(models.Model):
user = models.ForeignKey(CustomUser, related_name='card_numbers',null = True, blank=True, on_delete=models.CASCADE)
card_number = models.IntegerField(
verbose_name="Card Number", blank=True, null=True, default=None, unique=True)
def __int__(self):
return self.card_number
Serializer:
class CheckCard(serializers.Serializer):
card_number = serializers.IntegerField(write_only=True)
class Meta:
fields = ['card_number','user']
read_only_fields = ['user']
Views:
class CheckCardAPI(APIView):
permission_classes = [AllowAny]
serializer_class = CheckCard
def post(self,request,*args,**kwargs):
serializer = self.serializer_class(data=request.data)
card_number = request.data.get('card_number','')
if cardModel.objects.filter(card_number=card_number).exists():
user = User.objects.filter(card_numbers=card_number)
tokens, created = Token.objects.get_or_create(user=user)
return Response({'token':tokens.key},status=status.HTTP_200_OK)
else:
return Response({'error':'card is not registered'},status=status.HTTP_404_NOT_FOUND)
You are looking for a single user based on card number, so your query
user = User.objects.filter(card_numbers=card_number)
returns a list. Maybe you would need to use
user = User.objects.get(card_numbers=card_number)
to get an object or use
value_list(id, flat=True)
with filter.
I'm trying to build a form that automatically fills some fields in a class based create view that lets logged in users create a Job. However, I can't seem to find the correct way of doing this for fields that aren't the user (eg. request.user).
So the create view is trying to get a company_name from the logged in user, company_name field belongs to a model called Company. Each Company has an owner with a foreign key to the User model. All the reuest I've tried so far have led to a 'WSGIRequest' error.
So far I've tried to request:
company_name
user.company_name
company.company_name
company
user
I don't understand how these requests work, I have seen examples for getting the logged in users name and I'm not familiar how to do this otherwise.
Please can someone help me understand how this works and how I should be doing this?
I'm using Django 2.2 with python 3.6
Auth Models:
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone_number = models.CharField(max_length=15)
email = models.EmailField(max_length=250, unique=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
objects = UserManager()
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
def __str__(self):
return self.first_name
def get_absolute_url(self):
return "/users/%i/" % self.pk
class Company(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
company_name = models.CharField(max_length=100, unique=True)
company_address = models.CharField(max_length=100, unique=True)
company_website = models.URLField(blank=True, null=True)
company_verified = models.BooleanField(default=False)
def __str__(self):
return self.company_name
View
class JobCreateView(LoginRequiredMixin, CreateView):
model = Job
form_class = JobForm
template_name = 'jobs/job_create.html'
def form_valid(self, form):
form.instance.company_name = self.request.user
form.instance.job_reference = self.request.job.pk
return super(JobCreateView, self).form_valid(form)
def get_success_url(self):
return reverse('jobs:job_details', kwargs={'pk': self.object.pk})
Other Model:
class Job(models.Model):
JOB_TYPE = (
('1', 'Service'),
('2', 'Repair'),
('3', 'Quotation'),
('4', 'Consultation'),
('5', 'Report'),
('6', 'Design'),
)
ACCOUNT_TYPE = (
('1', 'Existing Customer'),
('2', 'Charge to Account'),
('3', 'New Customer'),
('4', 'Pre-Paid/C.O.D'),
('5', 'Issued and Acc App'),
)
company_name = models.ForeignKey(Company, related_name='jobs', verbose_name="Company Name", on_delete=models.CASCADE)
job_reference = models.CharField(max_length=50, blank=False)
contact_person = models.CharField(max_length=50)
contact_number = models.IntegerField()
contact_person_email = models.EmailField(max_length=100, blank=True, null=True)
site_address = models.CharField(max_length=100)
job_type = models.CharField(choices=JOB_TYPE, max_length=50, default='1')
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=50, default='1')
job_details = models.CharField(max_length=1000)
created = models.DateTimeField(default=now, blank=True)
def __str__(self):
return str(self.company_name)
def get_absolute_url(self):
return reverse('jobs:detail', kwargs={'pk': self.pk})
For anyone trying to solve a problem like this, the answer is;
Views:
class JobDocketCreate(CreateView):
model = JobDocket
form_class = JobDocketForm
template_name = 'jobs/job_docket_create.html'
def form_valid(self, form):
form.instance.technician = self.request.user
form.instance.job = Job.objects.get(pk=self.kwargs['job_pk'])
print(form.instance.job)
print(form.instance.technician)
context = {'job_pk':self.kwargs['job_pk']}
return super(JobDocketCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(JobDocketCreate, self).get_context_data(**kwargs)
context['job_pk'] = self.kwargs['job_pk']
return context
def get_success_url(self):
return reverse('jobs:my_job_dockets')
Form action in View:
action="{% url 'jobs:create_job_docket' job_pk %}"
Am having two model classes user and accounts linked by together or connected by another table called useraccounts.
What i want is for the useraccounts table to be automatically also be populated with the ids of the user and account table when i submit data to them(user and accounts).
here is my sample models code.
class Account(models.Model):
# fields
id = models.IntegerField(primary_key=True)
t_stamp = models.DateField(default=datetime.datetime.now())
acctno = models.TextField(null=False, unique =True)
acctname = models.TextField(null=False)
status = models.TextField(null=False, choices=STATUS)
accttype = models.TextField(null=False,choices=ACCT_TYPE)
acctclass = models.TextField(null=False, choices=ACCT_CLASS)
min_balance = models.FloatField(default=0)
cur_balance = models.FloatField(default=0)
ava_balance = models.FloatField(default=0)
#fundingsources = models.ManyToManyField(FundingSource)
class Meta:
managed = False
db_table = 'accounts'
def save(self, *args, **kwargs):
super(Account, self).save(*args, **kwargs)
try:
self.useraccount_set.all()[0]
except:
UserAccount.objects.bulk_create([UserAccount(account_id=self,user_id=user) for user in User.objects.all()])
class User(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True)
username = models.TextField(unique=True, null=True)
fullname = models.TextField(null=False)
country = models.TextField(null=True)
email = models.EmailField( unique=True, db_index=True)
phone = models.TextField()
address = models.TextField()
activation_key = models.CharField(max_length=40)
key_expires = models.DateTimeField(null=True)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=True)
#accounts = models.ManyToManyField(Account, through='UserAccount')
class Meta:
db_table = "users"
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def get_short_name(self):
return self.fullname
def get_username(self):
return self.email
def is_authenticated(self):
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
signals.post_save.connect(create_auth_client, sender=User)
User._meta.get_field_by_name('email')[0]._unique=True
class UserAccount(models.Model):
user_id = models.ForeignKey(User)
account_id = models.ForeignKey(Account)
class Meta:
managed = False
db_table = 'useraccounts'
class UserAccount(models.Model):
user_id = models.ForeignKey(User)
account_id = models.ForeignKey(Account)
class Meta:
managed = False
db_table = 'useraccounts'
You have to do that in model save method:
class Account(models.Model):
id = models.IntegerField(primary_key=True)
def save(self, *args, **kwargs):
super(Account, self).save(*args, **kwargs)
try:
self.useraccount_set.all()[0]
except:
UserAccount.objects.bulk_create([UserAccount(account_id=self,user_id=user) for user in User.objects.all()])
class User(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True)
def save(self, *args, **kwargs):
super(User, self).save(*args, **kwargs)
try:
self.useraccount_set.all()[0]
except:
UserAccount.objects.bulk_create([UserAccount(user_id=self,account_id=account) for account in Account.objects.all()])