Following are my models:
class A(models.Model):
owner = models.ForeignKey(User, null=False)
a_name= models.CharField(max_length=200, null=False, unique=True)
class B(models.Model):
owner = models.ForeignKey(User)
b_name= models.CharField(max_length=100, null=False)
class C(models.Model):
a= models.OneToOneField(
A,
on_delete=models.CASCADE,
null=False,
unique=True,
)
b= models.OneToOneField(
B,
on_delete=models.CASCADE,
null=False,
unique=True,
)
class D(models.Model):
c= models.OneToOneField(C,
on_delete=models.CASCADE,
null=False,
unique=True,
)
d1 = models.IntegerField(null=False, default=1)
I am trying to override the queryset in ListView generic class to get the list of all the objects in model 'D' where the 'owner' in model 'A' in current logged in user. I am unable to write the filter for the query.
D.objects.filter(self.c__a__owner==self.request.user)
But I am getting error as:
'MyListView' object has no attribute 'c__a__owner'
Please guide me how to achieve this.
Thanks.
Your query shouldn't have self. Also, you use a keyword assignment instead of a comparison in the filter method. It should like:
D.objects.filter(c__a__owner=self.request.user)
Related
I have two models. What i need is to reference the name and the email field from the Users model to the Customer model fields. Is the following way correct?
class Users(AbstractBaseUser):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
from users.models import Users
class Customer(models.Model):
user = models.OneToOneField(
Users, on_delete=models.CASCADE, null=True, blank=True)
name = models.OneToOneField(
Users.name, on_delete=models.CASCADE, null=True, blank=True)
email = models.OneToOneField(
Users.email, on_delete=models.CASCADE, null=True, blank=True)
class Users(AbstractBaseUser):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
class Customer(models.Model):
user = models.OneToOneField(
Users, on_delete=models.CASCADE, null=True, blank=True)
That's all. Then you can do for example
Customer.objects.get(pk=1).user.name
I have the two models, One is the User model and the other is a Contact model.
The Contact model is as follows:
class Contact(models.Model):
pass
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, on_delete=models.CASCADE, verbose_name=_('User'), related_name="user")
contact = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, null=True, on_delete=models.CASCADE, verbose_name=_('Contact'), related_name="contact")
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
is_contact = models.BooleanField(default=False)
Basically, what is does is create a contact for a user. Kind of a friend request and accept simple model. So the loggedIn user(request.user) could be either the contact.user or contact.contact.
And the settings.AUTH_USER_MODEL is a CustomUser model:
class CustomUser(AbstractUser):
pass
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=20, default="", blank=True)
last_name = models.CharField(max_length=20, default="", blank=True)
How can I create a relationship, where I can get a users contact by doing something like this:
// get user contacts user=CustomUser.objects.get(pk=1)
user.contacts.objects.all()
Typically you query reverse relations using the related_name keyword, which is contact_set by default:
user.contact_set.all()
If you want to change the name of this reverse relationship, you need to do so in the Contact model using related_name:
class Contact(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="contacts", ...)
user.contacts.all()
im implementing a simple API CRUD using Django + Django rest and have a doubt.
I have two models:
class Shoe(models.Model):
_id = models.AutoField(primary_key=True)
description = models.CharField(max_length=100, null=False, blank=False)
provider = models.CharField(max_length=100, null=False, blank=False)
type = models.CharField(max_length=2, choices=TIPO_CHOICES, null=False, blank=False)
cost_price = models.DecimalField(
max_digits=6, decimal_places=2, verbose_name = 'Preço de Custo',
null=False, blank=False
)
sale_price = models.DecimalField(
max_digits=6, decimal_places=2, verbose_name = 'Preço de Venda',
null=False, blank=False
)
class Stock(models.Model):
_id = models.AutoField(primary_key=True)
id_shoe = models.ForeignKey(
Shoe, on_delete = models.CASCADE, verbose_name = 'shoe', related_name = 'stock')
size = models.IntegerField(choices=NUMERACAO_CHOICES, null=False, blank=False)
amount = models.IntegerField(null=False, default=0)
What I am wanting is, when someone tries to make an insertion of stock of a size (of a certain shoe) that already exists it returns error. I can not just be 'unique' in the parameters of size. Any suggestions on how to do this?
Since you want only one Stock item for each unique combination of shoe and size, you can use unique_together [Django-doc] here:
class Stock(models.Model):
shoe = models.ForeignKey(Shoe, on_delete=models.CASCADE, verbose_name='shoe', related_name='stock')
size = models.IntegerField(choices=NUMERACAO_CHOICES, null=False, blank=False)
amount = models.IntegerField(null=False, default=0)
class Meta:
unique_together = ('shoe', 'size')
Note the name of a ForeignKey is usually not prefixed or suffixed with id_ or _id, Django automatically creates a "twin" field with the _id suffix that stores the primary key of the referenced value.
Note: If you do not specify a primary key, Django will automatically make one named id, so here it is probably better to let Django implement the logic.
if you are using Django 2.2 you can use UniqueConstraint instead of unique_together like this:
class Meta:
constraints = [
models.UniqueConstraint(fields=['shoe', 'size'], name='give_it_some_name')
]
As the docs state:
Use UniqueConstraint with the constraints option instead.
UniqueConstraint provides more functionality than unique_together. unique_together may be deprecated in the future.
Hello I have model like
class mymodel(models.Model):
a = models.CharField(blank=True, null=True, max_length=255)
b = models.CharField(blank=True, null=True, max_length=255)
c = models.CharField(blank=False, null=False, max_length=255)
Since I'm using the django admin as a back-end controller of the data stored in my model I want to make either one of them to not be null
for example the user must either fill a or either fill b or both to be filled, but if both are empty must throw an error
You can add custom validation like this
class mymodel(models.Model):
a = models.CharField(blank=True, null=True, max_length=255)
b = models.CharField(blank=True, null=True, max_length=255)
c = models.CharField(blank=False, null=False, max_length=255)
def clean(self):
if not (self.a and self.b):
raise ValidationError(....)
As a follow-up to this question, I'd like to pinpoint the actual error that was occurring. Am I doing something wrong, or is this a bug?
f = {'groups__isnull': 'True'}
students1 = models.Student.objects.filter( **f )
students2 = models.Student.objects.filter(groups__isnull=True)
These two queries should be identical, but are not.
For reference, my models:
class Student (models.Model):
user = models.ForeignKey(User, unique=True, null=False, related_name='student')
teacher = models.ForeignKey(User, null=False, related_name='students')
assignment = models.ForeignKey(LabJournal, blank=True, null=True, related_name='students')
class JournalGroup (models.Model):
title = models.CharField(null=False, max_length=256)
owner = models.ForeignKey(User, null=True, related_name='journal_groups')
members = models.ManyToManyField(Student, blank=True, related_name='groups')
I see an obvious difference between queries.
{'groups__isnull': True} is never equal to {'groups__isnull': 'True'}.
One provides True as boolean, other as a string.