I am creating a django site/platform where the main concept is users can create shops and other users can subscribe to those who have shops open (think Etsy). Trying to implement the subscriber feature and this is a model I have so far for it:
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
It works perfect for giving users the ability to subscribe and have the subscribtions listed in their profile and vice versa for shop owners, but for now a user can subscribe to a shop as many times as they want and I would like to prevent this. Idk if there is a constraint to allow multiple subscriber model instances by the same user but not allow for the same exact 'user' and 'sub_shop' instance OR if I am just going on about this in a very bad way!
You can use a UniqueConstraint [Django-doc] to specify that the combination of user and sub_shop should be unique:
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'sub_shop'],
name='subscribe_once'
)
]
prior to django-2.2, you can work with unique_together [Django-doc]:
# prior to Django-2.2
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
class Meta:
unique_together = [['user', 'sub_shop']]
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.
Related
I would like to create a bidirectional one-to-many and many-to-one relationship in django like:
class User(models.Model):
device = dont_know_what_to_write()
class Device(models.Model):
user = models.ForeignKey(
User,
on_delete = models.CASCADE
)
What should I do?
In Django if you define a relation from A to B, then Django will automatically add a conceptual relation from B to A which you can query. Django thus already has added the relation in reverse. Indeed, if you implement the models with:
class User(models.Model):
# no device
pass
class Device(models.Model):
user = models.ForeignKey(
User,
on_delete = models.CASCADE
)
then you can access the set of device related to the user with:
myuser.device_set.all()
this is a QuerySet that will contain all Devices that have myuser as user.
You can specify another name with the related_name=… parameter [Django-doc]:
class Device(models.Model):
user = models.ForeignKey(
User,
on_delete = models.CASCADE,
related_name='devices'
)
then you can obtain the devices with:
myuser.devices.all()
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.
I have the following models:
class User(AbstractUser):
pass
class Post(models.Model):
post_user = models.ForeignKey(User, on_delete=models.CASCADE)
post_content = models.TextField()
post_date = models.DateTimeField(default=timezone.now)
class Follow(models.Model):
follow_user = models.ForeignKey(User, on_delete=models.CASCADE)
follow_target = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follow_target')
I'm trying to create a queryset of all posts that were created by users I follow (me being the currently logged in user). My queryset currently looks like this but I keep getting NameError: field not found:
postresult = Post.objects.all().filter(post_user=follow__follow_target, follow__follow_user=request.user)
Any help will be greatly appreciated!
You filter with:
postresult = Post.objects.filter(
post_user__follow_target__follow_user=request.user
)
The post_user will follow the ForeignKey from Post to User. Then we use the related_name='follow_target' to follow the relation to the Follow object, and then we use follow_user to retrieve the following user.
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.
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the User model to the Follow
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the follow_target relation to followers.
In case you rename the related name, the query is thus:
postresult = Post.objects.filter(
post_user__followers__follow_user=request.user
)
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.
I have two objects, Company and Account, in different packages.
They have a many-to-many relation through employee, which has an additional field is_admin.
In Company I define the relation, and reading online, it seems that I don't have to redifine the relation in Account (this will result in a circular import).
Retrieving all the Accounts from the CompanySerializer is no problem,
but I need to be able to get all the Companies registered to an account as well.
This is my thinking:
Account Model:
class Account(AbstractBaseUser):
current_jobs = models.ManyToManyField(
Company, through='Employee') // I need to define current_jobs in some way
//,but this results in circular import
Company Model:
class Company(models.Model):
employees = models.ManyToManyField(
settings.AUTH_USER_MODEL, through='Employee')
Employee Model:
class Employee(models.Model):
class Meta:
unique_together = ('user', 'company')
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
is_admin = models.BooleanField()
The problem is, how will I now define how to get each of the lists in the serializers of the two.
So the Company Serializer, and the Account Serializer...
If i do not define current_jobs, I get an error stating that current_jobs is not defined, which it ofcourse is not.
I don't understand why you think you need to define current_jobs on Account. That is automatically provided for you via the reverse relationship as company_set; if you need it to be current_jobs you can set the related_name attribute.
The site I'm building allows users to create "posts" and has a Twitter-like concept of followed users. For a given user, I'd like to show all of the posts from the users that they follow.
Here are my simplified models:
class User
# a standard django.contrib.auth user model
class UserProfile(models.Model):
# my AUTH_PROFILE_MODULE for django-profiles
user = models.ForeignKey(User, unique=True)
following = models.ManyToManyField('self', symmetrical=False, related_name="followed_by")
class Posts(models.Model):
user = models.ForeignKey(User)
post = models.TextField()
Question: How do you create a queryset of all Post objects from the Users that a given User is following?
I think I've made it more complicated by creating the "follow" relationship on UserProfile, which is not the model with the ForeignKey relationship with Posts.
UPDATE! Here's the answer:
Posts.objects.filter(user__userprofile__in=UserProfile.objects.get(user=your_user_object).following.all())
Posts.objects.filter(user__in=UserProfile.objects.get(user=your_user_object).following)