Django: is it possible to exclude ForeignKey in derived model - django

i have this model
class Base(models.Model):
text = models.TextField()
description = models.TextField()
user = models.ForeignKey(User)
above model is inherited in following model:
class Profile(Base):
email = models.TextField()
sent = models.BooleanField()
Profile has user , a ForeignKey, which is not required here
Is that possible to get away with userfield in Profile ?

No, that is explicitly not supported, as the documentation explains.

Related

How to use a serializer for different fields

I am working on a project of blog application in Django Rest Framework. But here I am facing some trouble. At first checkout my code then I will explain the question.
Here is the model.py
class Contact(models.Model):
id_no = models.AutoField(primary_key=True, unique=True)
email = models.EmailField()
name = models.CharField(max_length=1000)
subject = models.CharField(max_length=1000)
description = models.TextField()
And here is the serializer.py
class AddContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = '__all__'
Now in a view function I want to use only email and name field of the Contact model and in another view function I want to use name and description field of that model.
Can I use the same serializer class for different cases?
Please help me.
You can create multiple seralizers for a model. Example
class EmailContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = ['email','name'] # your desired fields here

Django models: Unique values for foreign keys

I am building an Instagram like app and trying to make a like model. Each user can like a post however, it should not be possible to like the same post twice.
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
This is my model however, I am able to create 2 identical objects. For example user 1 can have 2 like objects like to post 1.
Is there a way to do this?
Yes, you can mark the combination of the user and post field as unique with a UniqueConstraint [Django-doc]:
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'post'], name='like_once')
]
Prior to django-2.2, you can make use of the unique_together option [Django-doc]:
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = [['user', 'post']]
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django ModelForm: Huge ForeignKey queryset leads to crash when loading form

Basically, I have two models: User and Event. An event is always associated with one user.
class User(models.Model):
user_id = models.AutoField(primary_key=True)
username = models.CharField(max_length=255, unique=True)
hashed_password = models.CharField(max_length=255)
class Event(models.Model):
event_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=255)
description = models.TextField(max_length=255, blank=True, default='')
user = models.ForeignKey(User)
And then I have the following form for Event.
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['title', 'description', 'user']
I can succesfully show this form in my template to create an event. I can also associate a user to a form successfully with Select field when the users number are still few.
Now the problem is, when I have 1M users in database, my browser crashes when loading the template. Any idea how to solve this one? I was thinking about using AJAX and then search user that matches the username, but I'd like to hear other better approaches. Thanks!

Django composite unique on multiple model fields

Let us say I have a model for social network posts, users and likes:
class Post(models.Model):
submitter = models.ForeignKey(User, null=False, default=None)
content = models.CharField()
date = models.DateField()
with_likes = PostLikeCountManager()
objects = models.Manager()
class Like(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
time = models.DateTimeField(auto_now_add=True)
It would be helpful to think of Post model as representing a Facebook post. Now, I would like to limit one like per post per user. How do I achieve that? One way would be to create a composite primary key on (user, post) attributes of Like class. I don't know how to achieve that in Django. The other would be to use unique=True on two attributes simultaneously. Is that possible?
Thanks.
Yes, use unique_together:
class Like(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
time = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('user', 'post')
unique_together will be deprecated in the future version, instead you could apply UniqueConstraint. This and this link gives example code.
class Like(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
time = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'post'], name='unique_user_post'),
]

Model relationship in Django

I have a model for conversations between two users.
class Conversation(models.Model):
users = models.ManyToManyField(User)
recipient1_pk = models.CharField(max_length=100)
recipient2_pk = models.CharField(max_length=100)
And I have a child model for messages. I'd to include a Boolean field that would allow each user to toggle the visibility of the conversation. BUT I don't want this to affect the conversation for the other user so I can't just add it to the conversation model. Is there an efficient way for me to add a boolean field for each user to do this whilst still sharing the same conversation model?
Have a look at adding extra fields to your ManyToManyField via the through parameter:
class Conversation(models.Model):
users = models.ManyToManyField(User, through='ConversationPreferences')
recipient1_pk = models.CharField(max_length=100)
recipient2_pk = models.CharField(max_length=100)
class ConversationPreferences(models.Model):
user = models.ForeignKey(User)
conversation = models.ForeignKey(Conversation)
visibility = models.BooleanField()