Django Rlationships levels - django

I have 3 models : User, Attribute, Site.
class User(models.Model):
userid = models.CharField(max_length=200, primary_key=True)
name= models.BooleanField(null=True)
def get_absolute_url(self):
return reverse('myapp:index')
def __str__(self):
return self.userid
class Site(models.Model):
pK_site = models.CharField(max_length=200, primary_key=True)
name = models.CharField(max_length=200,null=True)
def __str__(self):
return self.pK_site
class Attribute(models.Model):
userid = models.ForeignKey(User, on_delete=models.CASCADE)
role= models.CharField(max_length=200)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
def __str__(self):
return str(self.site)
def get_absolute_url(self):
return reverse('myapp:edit', kwargs={'pk' : self.userid.pk})
My problem is when i get for example the list of all the attribues (Class : Attribute) in a view, i can't get the Site of this attribute or its user in the template.
Someone has a suggestion to do that ? thank you

Related

query set in django

i really need help with this:
I have 3 models say User,Item and Comment where User is a foreign key in Item and Item is a foreign key in Comment.
i want to get all comment belonging to a particular user in my view, how do i achieve it. bellow is are my model
class User(models.Model):
name= models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Item(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
name= models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Comment(models.Model):
user = models.ForeignKey(Item, on_delete=CASCADE)
name= models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
there is a problem of design model in your code.
here is how you can do it.
class Comment(models.Model):
item = models.ForeignKey(Item, on_delete=CASCADE) # the related item
author = models.ForeignKey(User,on_delete=CASCADE) #new ( the author of the comment)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
now in your views.py you can do something like this.
Comment.objects.filter(author=request.user)
UPDATED 2
You should consider changing model, like amadou-sow said, that is right way to do such things
UPDATED
def get_user_comments(request):
qs = Comment.objects.filter(user__user=request.user)
You could access yours related objects with "__" (double _) read more in official docs
And you really should rename "user" field to "item" in Comment model if it is foreign key to Item model, like this:
class User(models.Model):
name= models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Item(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
name= models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Comment(models.Model):
item = models.ForeignKey(Item, on_delete=CASCADE)
name = models.CharField(max_length=200,null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
#view.py
def get_user_comments(request):
return Comment.objects.filter(item__user=request.user)

'function' object has no attribute 'order_by'

i am creating a simple blog website in django and have a model which contains time at which the blog will be published when in views i am trying to sort the post according to time it is giving error 'function' object has no attribute 'order_by'
my views.py:
class AboutView(TemplateView):
template_name = 'blog/about.html'
class Postlistview(ListView):
model = Post
def get_queryset(self):
return Post.objects.filter(published_date__lte=timezone.now.order_by('-published_date'))
my models.py :
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField(max_length=200)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = models.DateTimeField(default=timezone.now)
self.save()
def get_absolute_url(self):
return reverse('post_detail', kwargs={'pk': self.pk})
def approve_comments(self):
return self.comments.filter(approved_comments=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('blog.Post', related_name='comments', on_delete=models.CASCADE)
text = models.CharField(max_length=200)
author = models.CharField(max_length=20)
create_date = models.DurationField(default=timezone.now)
approved_comments = models.BooleanField(default=False)
def approve(self):
self.approved_comments = True
self.save()
def get_absolute_url(self):
return reverse('post_list')
def __str__(self):
return self.text
i think it is rather like this:
return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
the order_by must be outside of your filter.

How to Nested Categories in django admin

I want to create muti category in my ecommerce website where sub category will be dependent on main category.
Please help me with this
class MainCategory(models.Model):
# name = models.CharField(max_length=50)
# date_created = models.DateTimeField(auto_now_add=True)
# def __str__(self):
# return self.name
# class SubCategory(models.Model):
# perentcategory = models.OneToOneField(MainCategory, on_delete=models.CASCADE, primary_key=True)
# name = models.CharField(max_length=50)
# date_created = models.DateTimeField(auto_now_add=True)
# def __str__(self):
# return self.name
# class Items(models.Model):
# main = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
# name = models.CharField(max_length=255)
Posting this question 4th time
Change models.OneToOneField to models.ForeignKey so you can have multiple subcategories assigned to a main category:
class MainCategory(models.Model):
name = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class SubCategory(models.Model):
main_category = models.ForeignKey(MainCategory, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Items(models.Model):
main = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
You can use single model to accommodate both Category and Sub-categories. Something like this.
class Category(models.Model):
name = models.CharField(blank=False, max_length=200)
slug = models.SlugField(null=False)
parent = models.ForeignKey('self',blank=True, null=True ,related_name='children', on_delete=models.SET_NULL)
Then add following function to the above model
def get_categories(self):
if self.parent is None:
return self.name
else:
return self.parent.get_categories() + ' -> ' + self.name
def __str__(self):
return self.get_categories()
This will return structure similar to this image

Django foreign key and one-to-many relationship

I'm trying to build a basic ecommerce website, as a mean to learning django. I'm trying to build my models, so that there is a Category, a Product and Product Image class to store my data in. This is my models.py:
class Category(models.Model):
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
class Meta:
ordering = ('name', )
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products:product_list_by_category', args=[self.slug])
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name', )
index_together = (('id', 'slug'), )
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products:product_detail', args=[self.id, self.slug])
class ProductImage(models.Model):
property = models.ForeignKey('Product', related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='products')
And this is my views.py:
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(available=True)
product_img = Product.images.all()
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category=category)
return render(request, 'products/list.html', {'category': category, 'categories': categories, 'products': products, 'product_img': product_img})
I've seen similar post here on stack overflow, and have tried to do the same thing, but I still get the following error: AttributeError: 'ReverseManyToOneDescriptor' object has no attribute 'all'
Where am I going wrong here?

Django ManyToManyField Foreign Key Design

As part of an Address Book application, I have the following in my models.py
from django.db import models
class Contact(models.Model):
contact_id= models.AutoField(auto_created=True, primary_key=True, default=1, verbose_name='ID')
name = models.CharField(max_length=100, unique=True)
contact_no = models.ManyToManyField(ContactNumberTypeField,
through='ContactContactNumber', through_fields=('contact_name','contact_type'))
def __str__(self):
return self.name
class ContactNumberTypeField(models.Model):
contact_number_type=models.AutoField(auto_created=True, primary_key=True, default=1, verbose_name='ID')
name = models.CharField(max_length=20)
contact_no = models.ManyToManyField(Contact,
through='ContactContactNumber', through_fields=('contact_name','contact_type'))
def __str__(self):
return self.name
class ContactContactNumber(models.Model):
contact_name=models.ForeignKey(Contact)
contact_type=models.ForeignKey(ContactNumberTypeField)
contact_number = models.CharField(max_length=50)
def __str__(self):
return contact_number
My question is that why is it when I run makemigrations, it throws a ContactNumberTypeField is not defined error?
Update
Correct code is as follows
from django.db import models
class Contact(models.Model):
contact_id= models.ManyToManyField('ContactNumberTypeField',
through='ContactContactNumber', through_fields=('contact_name','contact_type'))
name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.name
class ContactNumberTypeField(models.Model):
contact_number_type=models.ManyToManyField('Contact',
through='ContactContactNumber', through_fields=('contact_type','contact_name'))
name = models.CharField(max_length=20)
contact_no = models.IntegerField(max_length=20)
def __str__(self):
return self.name
class ContactContactNumber(models.Model):
contact_name=models.ForeignKey(Contact)
contact_type=models.ForeignKey(ContactNumberTypeField)
contact_number = models.CharField(max_length=50)
def __str__(self):
return contact_number
ContactNumberTypeField is not defined at the time of defining of Contact class. Change contact_no field to this:
class Contact(models.Model):
...
contact_no = models.ManyToManyField('ContactNumberTypeField',
through='ContactContactNumber',
through_fields=('contact_name','contact_type'))
Note the quotes around 'ContactNumberTypeField'.
The other error here is the wrong order of field names in through_fields attribute of the ContactNumberTypeField.contact_no field. It should be:
class ContactNumberTypeField(models.Model):
...
contact_no = models.ManyToManyField(Contact,
through='ContactContactNumber',
through_fields=('contact_type','contact_name'))
Read the documentation about field1 and field2.