Auto pass or recieve a ForeignKey instance value - python

Say I have a Profile Model that gets created automatically from auth.models.User by using signals and on the Profile model OneToOneField, I have a company attribute tied to a Company model by ForeignKey. Meanwhile this Company model gets created at signup too via Foreignkey using formset_factory in views. What I am aiming to achieve is having the Company instance created at signup passed to the Profile instance Foreignkey as well. Tried using signals, overiding save methods etc. doesn't seem to be working.
Here's a sample code, all suggestions are greatly appreciated in advance.
from django.contrib.auth.models import User
class Company(models.Model):
comp_admin = model.ForeignKey(User, on_delete=models.CASCADE)
comp_name = models.CharField(max_length=200)
.............................
.............................
other attributes omitted
.............................
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.ForeignKey(Company, on_delete=models.CASCADE)

Ok, literally, few minutes after asking this question, I figured it out. What I did was use post_save to update the company attribute, but checked if the Company instance had the same comp_admin attribute value as the user attribute value. I'm guessing overriding the init method will work as well, but seems a bit long.

Related

how to get a column value of foreign key in the form of object?

There is 2 models Registration and RegistrationCompletedByUser, I want Registration queryset from RegistrationCompletedByUser with filters(user=request.user, registration__in=some_value, is_completed=True) over RegistrationCompletedByUser. Hence result should be like <QuerySet [<Registration: No name>, <Registration: p2>, <Registration: p-1>]>.
Now what I tried is
Registration.objects.prefetch_related('registrationcompletedbyuser_set') but filters() not working. Another way I tried is model Managers but don't pass parameters for custom filtering.
models.py
class Registration(models.Model):
name=models.CharField(max_length=255)
number=models.SmallIntegerField(null=True, blank=True)
class RegistrationCompletedByUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
registration= models.ForeignKey(Registration, on_delete=models.CASCADE)
points = models.SmallIntegerField(default=100)
is_completed = models.BooleanField(default=False)
If I understood this properly, you want to get all Registrations that related to a query instead of a single object.
qs_1 = RegistrationCompletedByUser.objects.filter(user=request.user, is_completed=True).values_list("registration__id", flat=True)
qs_2 = Registration.objects.filter(id__in=qs_1)
As I understood your question is related to django. So actually there is common way to get related query set from another. When you specify ForeignKey to another model actually django automatically creates 'Related Model' + '_set' relation.
I actually didn't get from you question what you are intended to do. In your situation there are many RegistrationCompletedByUser related to one Registration. So what you can do it's to receive all RegistrationCompletedByUser instances from Registration instance by related name for ForeignKey registration of RegistrationCompletedByUser which in your case registration_set. Actually better to specify in RegistrationCompletedByUser model related name as attribute like this:
models.ForeignKey(Registration, on_delete=models.CASCADE,
related_name='registrations')
And after this let's say you have instance of Registration reg1. So to receive queryset of RegistrationCompletedByUser:
reg1.registrations.all()
And you can use filter on it with attributes from Registration model.
And if you want to receive Registration from RegistrationCompletedByUser, again in your case it's just one Registration to many RegistrationCompletedByUser, so let's say we have reg_completed_1, to receive it's only one registration:
reg = reg_completed_1.registration

How i could use the "username" from the User model as id in other model in Django?

I'm new in this and I'm trying to use in Django the username as id in other model.
I imported the base model for User in Django, but when i'm doing:
author = User().get_username()
The field doesn't appear.
Is there any method to use the "username" from the User model?
Thanks for your help and sorry for my English.
You need to use ForeignKey to relate your current model with User model to access its methods.
class MyModel(models.Model):
author = models.ForeignKey('User', on_delete=models.CASCADE)
...
Then you can call .get_username() method to retrieve username. Assuming my_obj is MyModel class object, calling my_obj.author.get_username() will do the job.

Django: how to change a base object to an alone subclass object?

Now I'm working with python django.
I have derived a Model class from user:
from django.contrib.auth.models import User
class Customer(User):
mobile = models.CharField(max_length=14)
class Meta:
db_table = 'customer_user'
Question
Now comes the question, I have some normal user object, which is not yet a CustomerUser object.
>>> john = User.objects.get(username='john')
>>> hasattr(john.customer)
False
Infact the john object has a row in the user table in database, but has no row in the customer table.
I want to change john into a Customer object, i.e. adding a row of customer, pointing the parent link to the initial user object row.
I tried the following code, but did not work?
>>> Customer.objects.create(user=john, mobile='1234')
Is there any nice way to do the job?
You have two options, as described in the documentation:
1. Make your Customer model a proxy for the User model:
class Customer(User):
class Meta:
proxy = True
Then any instance of User is also an instance of Customer. Note that you probably don't want to set a custom table_name in this case because both models operate through the same table.
2. Make your Customer a profile model that has a one-to-one relationship with the core User model:
from django.contrib.auth.models import User
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile = models.CharField(max_length=14)
Then:
john = User.objects.get(username='john')
if not hasattr(john, 'customer'):
Customer.objects.create(user=john, mobile='1234')
The second approach seems to me to be a better fit for your use case.

Extending Django User with subclasses

Due to my app requeriments I need an hierachy of users classes like:
class CommonUser(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
photo = models.ImageField(upload_to="profileImages",blank=True,null=True)
#HERE: Common properties for every user
class Meta:
abstract = True
class Installer(CommonUser):
#HERE: Specific properties for Installer Companies
class Administration(CommonUser):
#HERE: Specific properties for Administration
class Client(CommonUser):
#HERE: Specific properties for Clients
Well, in view.py I need to get the profile image for an user. I get the user by the request, so I have an models.User objects and I dont know to witch class it belong. Im not able to do:
request.user.commonuser.photo
because user object doesnt have any OnetoOne relation with commonuser but with installer/administration/client...
Any idea? Thanks!
I'm on mobile, so I can't test this, but...
I would set a "related_name" on your CommonUser.user field called "commonuser". Then you can just use:
request.user.commonuser.photo
like you are already.
I think the issue is that you are referencing a Django User object to reference a backwards relationship without the proper name.
First off, I think this model is more of a Profile than User. If you don't mind using 1.9 (and postgres) then this is a perfect usecase for a JSON field. You can filter with regular lookups and don't need to specify each type. That way you can also extend the user model in such a way that a user can fulfill many roles at once. The other thing I thought of was linking it the other way around:
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
# ...
class Installer(models.Model):
profile = models.ForeignKey(UserProfile, related_name='installer')
#HERE: Specific properties for Installer Companies
class Administration(models.Model):
profile = models.ForeignKey(UserProfile, related_name='admin')
#HERE: Specific properties for Administration
class Client(models.Model):
profile = models.ForeignKey(UserProfile, related_name='client')
#HERE: Specific properties for Clients

Defining the name of a ManyToOne relationship in Django

I would like to define a django model which has many-to-one relationship with itself. It is a user profile, connected as a OneToOne field with the authentication user model. I would like to save which user (if any) was the one who referred the 'current' user to my system. This means I have the following definition:
class UserProfile(models.Model):
user = models.OneToOneField(User, blank=True, related_name='profile')
class Meta:
abstract = True
class SpecificUserProfile(UserProfile):
referrer = models.ForeignKey('self')
I saw the django defaults to naming the set of referenced models by the name of the class with a suffix _set. I believe I will be getting something along the lines of specific_user_profile_set. I would much prefer to have it named u1.referrer and u2.referred or u2.referred_set. Is there any way this can be achieved?
related_name='profile'
This is the argument to define a name for any related field, so:
class SpecificUserProfile(UserProfile):
referrer = models.ForeignKey('self', related_name='referred')

Categories