i'm new with Django and as I read the code, I don't understand the message_set attribute of Django model(called Room):
def room(request, pk):
room = Room.objects.get(id=pk)
**room_messages = room.message_set.all()**
participants = room.participants.all()
portion of Models:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(
User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
If you define a ForeignKey from Message to Room, Django will add a relation in reverse to the from the Room model to its related Messages. By default this relation is named modelname_set with modelname the name of the origin of the model. You can specify another name by overriding the related_name=… parameter [Django-doc].
If you thus access the relation in reverse, you get all Message objects with room as there room, an equivalent query to room.message_set.all() is thus Message.objects.filter(room=room).
Related
error image
I'm using the model and I keep running into problems with many to many. At first, I made it without giving an id value, but it seems that the id value is not entered, so when I put the id value directly, the same problem as above occurs. But in the Post model below, the same form of likes is used. Why?
from django.db import models
# from django.contrib.auth.models import User
from django.conf import settings
# from server.apps.user.models import Profile
# Create your models here.
class Clothes(models.Model):
CATEGORYS =[
(0, '상의'), #상의
(1, '하의'), #하의
(2, '아우터'), #아우터
(3, '신발'), #신발
(4, '악세사리'), #악세사리
]
category = models.IntegerField(default=0,choices=CATEGORYS)
id = models.IntegerField(primary_key=True)
img = models.ImageField(upload_to='main/images/clothes/%Y/%m/%d')
save = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Pickitems', blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
buying = models.TextField(null=True, blank=True)
def __str__(self):
return f'{self.id}: {self.category}'
#pk가 존재하지 않는것 같음.
# class SavePeople(models.Model):
class Post(models.Model):
main_img = models.ImageField(upload_to='main/images/post/%Y/%m/%d')
title = models.CharField(max_length=100)
content = models.TextField()
private = models.BooleanField(default=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
clothes = models.ManyToManyField(Clothes,related_name='Clothes')
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Likes', blank=True)
def __str__(self):
return f'{self.pk}: {self.title}'
def get_absolute_url(self):
return f'/community/'
#이거 나중에 detail page로 바꿔주세요
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'({self.author}) {self.post.title} : {self.content}'
class Commu(models.Model):
COMMU_CHOICES = [
('buying', 'buying'), #공동구매
('openrun', 'openrun'), #오픈런
('question', 'question'), #고민방
]
category = models.CharField(max_length=20, choices=COMMU_CHOICES)
img = models.ImageField(upload_to='main/images/commu/%Y/%m/%d', null=True, blank=True)
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return f'{self.pk}: {self.title}'
def get_absolute_url(self):
return f'/community/commu'
I added the code saves= models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Save', blank=True) to the Clothes model to make a save of Clothes in the same way as the likes of the Post model, but an error like the attached picture is displayed. occurred. When I searched, it seemed that the pk value did not exist.
The issue is the id field that you explicitly provided, Django itself creates an id field as a primary key for each model if you don't specify one. So, it is not necessary to add it to the model. Kindly remove it through the Clothes model and run migration commands.
And it doesn't give in case of likes since there is no extra field id in Post model unlike that of Clothes.
Note: Models in Django doesn't require s to be added as suffix, as it is automatically done, so you may change Clothes to Cloth.
I have the following model in Django
class Transfer(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, limit_choices_to={'is_accepted':True})
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to filter the users based on is_accepted field. The problem is, that this field is declared in a model called Employee, which is in onetoone relationship with user.
Is there any possibility to reach Employee fields and filter them in this manner?
You can normally define a filter like:
class Transfer(models.Model):
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
limit_choices_to={'employee__is_accepted': True}
)
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I have a model Comment:
class Comment(models.Model):
upload = models.ForeignKey(Upload, related_name='comments', on_delete=models.CASCADE)
user = models.ForeignKey(get_user_model(), related_name='comments', on_delete=models.CASCADE)
text = models.TextField(blank=False, null=False)
date_created = models.DateTimeField(auto_now_add=True)
And I also have a model BlockedUser:
class BlockedUser(models.Model):
blocked_by = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name="blocked_by")
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
How can I fetch all the comments except ones written by someone who you've blocked?
queryset = Comment.objects.all().select_related('user')
queryset = queryset.exclude(user__in=BlockedUser.objects.filter(blocked_by=self.request.user))
Which obviously doesn't work like that, but I am not sure how to write it so that it does work.
You can exclude Comments from a user for which there exists a BlockedUser with blocked_by the request.user with:
Comment.objects.exclude(user__blockeduser__blocked_by=request.user)
Cannot resolve keyword 'is_staff' into field. Choices are: dob, experience, id,user, user_id
I get the above error when adding trainer as a Foreign Key to the Subscription model and then accessing any record for Subscription model from admin panel
class Subscription(models.Model):
client = models.OneToOneField(ClientProfile, on_delete=models.CASCADE)
trainer = models.ForeignKey(TrainerProfile, null=True, blank=True,
on_delete=models.SET_NULL, limit_choices_to={'is_staff': True})
plan = models.ForeignKey(Plan, on_delete=models.CASCADE)
transaction = models.OneToOneField(PaymentHistory, on_delete=models.CASCADE)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
class TrainerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
dob = models.DateField(null=True)
experience = models.PositiveIntegerField(default=0)
You're trying to access an attribute is_staff, which does not exist on the TrainerProfile model. is_staff is an attribute of User, which you reference in your TrainerProfile model's user field.
In order to access this property, you need to "traverse" the relationship from Subscription -> TrainerProfile -> User. Django allows you to do this by using double-underscore notation, like this: some_fk_field__fk_field_attribute.
In your example, you need to change your limit_choices_to option on trainer to traverse the relationship to the user, like so:
class Subscription(models.Model):
client = models.OneToOneField(ClientProfile, on_delete=models.CASCADE)
trainer = models.ForeignKey(TrainerProfile, null=True, blank=True,
on_delete=models.SET_NULL, limit_choices_to={'user__is_staff': True})
plan = models.ForeignKey(Plan, on_delete=models.CASCADE)
transaction = models.OneToOneField(PaymentHistory, on_delete=models.CASCADE)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
class TrainerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
dob = models.DateField(null=True)
experience = models.PositiveIntegerField(default=0)
You are referencing the nested relationship in wrong way
class Subscription(models.Model):
# other fields
trainer = models.ForeignKey(TrainerProfile, null=True, blank=True,
on_delete=models.SET_NULL,
limit_choices_to={'user__is_staff': True})
That is, it should be user__is_staff instead of is_staff
In Django there are field types called ForeignKey and OneToMany/OneToOne, I was wondering would I use ForeignKey or the relationship type as the field type in this scenario? User to Profile has been identified as OneToOne but I'm unsure about the others.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
fullname = models.CharField(max_length=100)
dob = models.DateField()
address = models.TextField()
city = models.CharField(max_length=100)
profilephoto = models.ImageField(default='default_profile.jpg', upload_to='reviewApp/static/profile_images')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='default_product.jpg', upload_to='reviewApp/static/product_images')
class Review(models.Model):
product = models.ForeignKey(Product)
profile = models.ForeignKey(Profile)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = model.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
postdate = models.DateTimeField(auto_now_add=True)
lastmodified = models.DateTimeField(auto_now=True)
So from what I see here, it seems to be good if the following is what you want:
User can have only one profile and one Profile is related to only one user.
a Profile can make multiple Review but a Review belongs to only one profile.
A Product can have multiple Review but a Review is specific to one Product.
Be carefull to define the on_delete argument for your foreign keys depending of what you want to keep in your database after a delete.
More info from the doc : https://docs.djangoproject.com/fr/2.2/ref/models/fields/#arguments