I've created a referral system on my website. Admittedly, it's late and this might not be the right sort of relationship.
class Referral(models.Model):
referred=models.ForeignKey(User, related_name="referred")
referrer=models.ForeignKey(User,related_name="referrer")
def __unicode__(self):
return self.user.first_name
What would others recommend to represent this relationship? If this is about right, is there a way for me to turn this into a pseudo inline for the User Admin? It's not allowed as currently constructed because there are two foreign keys to teh same table.
Thanks
Actually, this is a ManyToMany relationship between User and itself - the Referral class itself does not add anything to the relationship.
Normally, you can just add the ManyToManyField to the model and it will be displayed in the admin - but I'm guessing that the User class you reference is the built-in django.contrib.auth User, which you can't directly modify. So one way would be to define a UserProfile class which has a ForeignKey to User, and add the ManyToMany relationship there.
Edit in response to comment No, that's not quite what I meant. I'm saying you should drop the Referral class completely. A model which is just two FKs and nothing else - whether they're both to the same model or not - is the through table of a M2M relationship. That relationship, in your case, is between User and itself - but as I say, since you don't want to change User, it is between a new UserProfile model and itself.
Related
I'm using Django, is there a way to apply foreign key and ChartField to one field at the same time? Sometimes I want to allow the user to enter a value that is not in the foreign key. I've googled for a long time and found various ways, but I can't find a solution. Please help.
[models.py]
class Supporting(models.Model):
assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE, blank=False, null=True)
Foreign key only allows ids or objects of models that it has relation with. it can never ever accept text. if you want to this field to be a foreign key for other models too then there is a solution. you can use generic foreign key
You Might be looking for a through Model between Supporting and Assignment.
As per your question, you might require multiple fields defining the nature of relation between two models and Through Models are exactly made for that!
Django Through Models Docs
You can't add ForeignKey and text in Django to a single field. You have to create a foreign key (Assignment) object, and then, after a page refresh, you can attach it to the current model.
I the page refresh is not needed, AJAX has to be used.
I am attempting to add the fields from a OneToOneField into my admin view. Here is an example of how my models look.
class Customer(BaseUser):
name = CharField()
address = CharField()
secondary_information = OneToOneField("SecondaryCustomerInfo", on_delete=SET_NULL, null=True)
class SecondaryCustomerInfo(models.Model):
email = EmailField()
And I tried adding in the fields as an inline like this.
class SecondaryCustomerInfoInline(admin.StackedInline):
model = SecondaryCustomerInfo
class CustomerAdmin(admin.ModelAdmin):
inlines = [SecondaryCustomerInfoInline]
But I get the error
<class 'user.admin.SecondaryCustomerInfoInline'>: (admin.E202) 'user.SecondaryCustomerInfo' has no ForeignKey to 'user.Customer'.
I'm used to putting the OneToOneField on the secondary model but my coworker asked that I put it on the main Customer model since we will be accessing that information more often. I think switching things around is what is tripping me up. How would I include the fields from SecondaryCustomerInfo on the admin view for Customer?
The answer would be to use Django Reverse Admin
From its documentation:
Module that makes django admin handle OneToOneFields in a better way. A common use case for one-to-one relationships is to "embed" a model inside another one. For example, a Person may have multiple foreign keys pointing to an Address entity, one home address, one business address and so on. Django admin displays those relations using select boxes, letting the user choose which address entity to connect to a person. A more natural way to handle the relationship is using inlines. However, since the foreign key is placed on the owning entity, django admins standard inline classes can't be used.
class CustomerAdmin(ReverseModelAdmin):
inline_type = 'stacked'
inline_reverse = ['secondary_information']
In one model I want to reference my user's first and last name as the str() which is a foreign key to the User model.
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}"
My issue is, in some of the models on Django Admin, there are hundreds of queries which will obvious go to thousands with more users. What is the best practice around avoiding this? In some of my custom views there are duplicates here, but it's not as big of a deal as it is with the admin panel.
Add to your ModelAdmin
list_select_related = ['user']
I am a Django dev and I’m stuck with a problem of reverse foreignkey lookup. The problem is described as follows:
I am working on query optimization. I have a model MicroMessage which has a foreignkey to User (from django.contrib.auth.models) as author. Also there are some other classes which have also foreignkey to User (e.g UserProfile).
I need a query which will fetch author of MicroMessage as well as all users related to any other model from which I can access the UserProfile info of that author without any excessive queries. I tried this:
MicroMessage.objects.select_reverse({'authors':'author_set'})
Please assist me. Thanks in advance.
You're looking for select_related
https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related
messages = MicroMessage.objects.select_related('author', 'author__userprofile')
The second field (a user's profile) is a reverse foreign key but if implemented as a OneToOneField as the docs suggest, can be queried in the manner shown above if the class was named UserProfile.
I have a class UserProfile defined which takes the default user as a foreign key.
Now another class A has a foreign key to UserProfile.
So for saving any instance in class A, how do i give it the userprofile object.
Also, does making a class UserProfile mean that class user is still used and class UserProfile is just some other table?
I need to know this as I have to take care of the user profile creation, so I should know what gets stored where?
--
Confused
So for saving any instance in class A,
how do i give it the userprofile
object.
Create a app with a model which has a models.OneToOneField(User) or a models.ForeignKey(User, unique=True).
Make your project aware of your UserProfile by pointing to it from the settings.py file AUTH_PROFILE_MODULE = 'myapp.UserProfile'.
Read the documentation.
Also, does making a class UserProfile
mean that class user is still used and
class UserProfile is just some other
table?
Yes, your database will have both a auth_user and a user_profile table. This is due to the fact that using UserProfiles doesn't mean all user have to have profiles. Only the additional fields defined in the UserProfile model will be in the user_profile table.
I need to know this as I have to take
care of the user profile creation, so
I should know what gets stored where?
James Bennett created two nice apps which with a few hours of careful reading will be of great help especially when it comes to the user registration part. Go look at django-registration and django-profiles.
I assume your UserProfile model is intended to store additional information about your users. If so, there's documentation about the best approach to do this, which in brief is:
define a model with fields for the additional information you'd like to store, or additional methods you'd like to have available, and also add a OneToOneField from your model to the User model. This will ensure only one instance of your model can be created for each User.
Set AUTH_PROFILE_MODULE to myapp.MyModel, where myapp is the app containing the model MyModel which you want to use to store extra information about your users.