Related
I have a model in my Django application for review. This model has two foreign keys to the product and user models. But when I go to the admin panel and try to add a new review I don't see the review models dropdown select for the foreign keys.
I'm expecting to see the foreign keys fields rendered in my admin panel as dropdown selects like in the blue box in the picture below.
Screenshot of my admin panel to add a new order object
But the admin panel doesn't show those fields. It only shows the name, rating, and comment fields.
Screenshot of my admin panel to add a new reivew object
Here is my review model.
class Reviews(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True),
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True),
name = models.CharField(max_length=350, null=True, blank=True)
rating = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True, default=0)
comment = models.TextField(null=True, blank=True)
createdAt = models.DateTimeField
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return str(self.rating)
In your Reviews model, you have put a comma at the end of users and product fields. Remove the trailing comma at the end, as the fields are considered as tuple when a comma is present.
It should be:
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
Also, your createdAt field is not correct.
It should be:
createdAt = models.DateTimeField()
Try it like this, i removed comma from user and product field in the end, also i have added () in DateTimeField
class Reviews(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=350, null=True, blank=True)
rating = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True, default=0)
comment = models.TextField(null=True, blank=True)
createdAt = models.DateTimeField()
I have the following related data models
class Cart(models.Model):
products = models.ManyToManyField('assortment.Product', through='CartProduct')
order = models.OneToOneField('Order', on_delete=models.CASCADE, related_name='order_cart', null=True)
user = models.ForeignKey('account.Profile', on_delete=models.CASCADE, related_name='user_carts', blank=True, null=True)
class CartProduct(models.Model):
product = models.ForeignKey('assortment.Product', related_name='product_cartproducts', null=True, on_delete=models.SET_NULL)
cart = models.ForeignKey('Cart', related_name='cart_cartproducts', null=True, on_delete=models.SET_NULL)
count = models.IntegerField(blank=False, null=False, default=1)
class Order(models.Model):
pay_date = models.DateField(auto_now_add=True)
is_paid = models.BooleanField(default=False)
My code below gives an error: invalid argument "products" in prefetch_related:
Order.objects.all().select_related('order_cart').prefetch_related('products')
How can I join all three models in one request?
The query builder continues with the original table (Order), thus you have to specify the fields relative to that or relative to the previously mentioned field. Try one of the following:
'order_cart__products'
'order_cart__cart_cartproducts'
(Notice the double underscore.)
I'm completely new to JSON and would like to understand how to interpret the following code. Basically, I asked my database to provide me with DB schema and this is what he gave me. I understand SQL and want to create a visual representation of schema of it. Can someone please simplify it.
class Vendor(models.Model):
AUTH_CHOICES = tuple(itertools.chain.from_iterable([(
('KEY', 'KEY'),
('PASSWORD', 'PASSWORD'),
('CUSTOM', 'CUSTOM'),
)]))
name = models.CharField(max_length=32, db_index=True, unique=True)
label = models.CharField(max_length=256, null=True, blank=True)
authentication_type = models.CharField(max_length=32, choices=AUTH_CHOICES, default='KEY')
authentication_inputs = jsonfield.JSONField(null=True, blank=True, default={},
dump_kwargs={'cls': JSONEncoder, 'indent': None,
'separators': (',', ':')})
tags = models.TextField(null=True, blank=True)
categories = models.TextField(null=True, blank=True)
is_hidden = models.BooleanField(default=False)
in_house = models.BooleanField(default=False)
feature = models.ForeignKey(Feature, related_name='vendor_features', null=True, on_delete=models.SET_NULL)
has_multiple_keys = models.BooleanField(default=False)
def __str__(self):
return self.label or self.name
class VendorApi(models.Model):
vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, related_name='apis')
name = models.CharField(max_length=32, db_index=True, unique=True)
label = models.CharField(max_length=256, null=True, blank=True)
plugin = models.CharField(max_length=64, null=True, blank=True)
def __str__(self):
return self.label or self.name
class VendorApiField(models.Model):
GROUP_CHOICES = tuple(itertools.chain.from_iterable([(
('COMPANY', 'COMPANY'),
('PERSON', 'PERSON'),
)]))
TYPE_CHOICES = tuple(itertools.chain.from_iterable([(
('STRING', 'STRING'),
('INTEGER', 'INTEGER'),
('FLOAT', 'FLOAT'),
('CURRENCY', 'CURRENCY'),
('DATETIME', 'DATETIME'),
('OBJECT', 'OBJECT'),
('ARRAY', 'ARRAY'),
('URL', 'URL'),
)]))
vendor_api = models.ForeignKey('VendorApi', related_name='fields', on_delete=models.CASCADE)
name = models.CharField(max_length=64, db_index=True, unique=False)
label = models.CharField(max_length=256, null=True, blank=True)
type = models.CharField(max_length=32, choices=TYPE_CHOICES, default='STRING')
example = models.CharField(max_length=256, null=True, blank=True)
description = models.CharField(max_length=256, null=True, blank=True)
rl_api_field = models.CharField(max_length=64, null=True, blank=True)
group = models.CharField(max_length=32, choices=GROUP_CHOICES, default='COMPANY')
class Meta:
unique_together = ('vendor_api', 'name', 'rl_api_field') ```
From what i can understand from Owners comment and questions. What you need is just to understand how the models are connected. Let me explain it to you.
1.) Vendor is a Model which is connected to another model named feature via foreign key relation(i.e one to many relationship)
2.) Vendor Api connects to Vendor Model via the same foreign key relation as above.
3.) Vendor ApiField connects to VendorApi model via foreign key relation.
To summarise:
Feature <-- Vendor <-- VendorApi <-- VendorApiField
Where <-- shows the relationship via foreign key. (i.e. one to many relationship)in sql
I have this model -
class News(BaseEntityBasicAbstract, HitCountMixin):
"""
News added from the dashboard with content
"""
NEWS_STATUS = (
('draft', _('Draft')),
('pending', _('Pending')),
('review', _('Review')),
('public', _('Public')),
('private', _('Private'))
)
backup = models.BooleanField(default=False)
prev_id = models.BigIntegerField(null=True, blank=True)
language = models.CharField(max_length=10, choices=LANGUAGES, default='bn', db_index=True)
heading = models.CharField(max_length=255, null=True, blank=True,
verbose_name=_('News Heading'),
help_text=_('Provide a news heading/caption.'))
sub_caption = models.TextField(max_length=255, null=True, blank=True,
verbose_name=_('Summary'),
help_text=_('Provide summary of the news.'))
url = models.CharField(max_length=255, unique=True, verbose_name=_('URL/Slug/Link'),
help_text=_('Unique url for the news without whitspace.'))
content = HTMLField(null=True, blank=True, verbose_name=_('Content'),
help_text=_('HTML content with texts, links & images.'))
featured_image = models.FileField(upload_to=FilePrefix('news/'), null=True, blank=True,
verbose_name=_('Featured Image'),
help_text=_('Upload a featured image for news.'))
image_caption = models.TextField(max_length=255, null=True, blank=True,
verbose_name=_('Image Caption'),
help_text=_('Provide a image caption.'))
status = models.CharField(max_length=20, choices=NEWS_STATUS, default='pending',
verbose_name=_('News Status'), db_index=True,
help_text=_('Only public news can be seen on front end.'))
source = models.ForeignKey(NewsSource, on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('News Source'),
help_text=_('Select a news source.'))
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Category'),
help_text=_('Select a news category.'))
tags = tagulous.models.TagField(
blank=True,
to=Tags,
verbose_name=_('News Tags'),
help_text=_('Provide news tags separated with commas.')
)
published_at = models.DateTimeField(null=True, blank=True, db_index=True,
verbose_name=_('Published At'))
menu_items = GenericRelation(MenuItems, object_id_field='id',
related_query_name='news_as_menu')
hit_count_generic = GenericRelation(HitCount, object_id_field='object_pk',
related_query_name='news_hit_count')
created_by = models.ForeignKey(User, related_name='news_created_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Created By'))
updated_by = models.ForeignKey(User, related_name='news_updated_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Last Updated By'))
published_by = models.ForeignKey(User, related_name='news_published_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Published By'))
deleted_by = models.ForeignKey(User, related_name='news_deleted_by',
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Deleted By'))
Below is the serializer -
class NewsSerializer(serializers.ModelSerializer):
class Meta:
model = News
fields = ['id', 'heading', 'sub_caption', 'url', 'content', 'featured_image',
'image_caption', 'category', 'source', 'tags', 'published_at']
This is the view -
class NewsViewSets(viewsets.ModelViewSet):
queryset = News.objects.filter(
is_active=True,
status='public'
)
serializer_class = NewsSerializer
def get_queryset(self):
queryset = self.queryset.filter(
language=self.request.LANGUAGE_CODE
).order_by('-id')
return queryset
Pagination is set to only 10 in the settings.py, when I hit the news api url it takes 9/10 seconds to load only 10 records. Here's a screenshot showing django-debug-toolbar reports -
I have around 400k records on the database table, it may be an issue, but I think this is too much loading time. Please help me find the problem here! Thanks in advance.
Filtering can often be slow. It looks like you have database indexes on the relevant fields, but take note that if you have multiple filters, only one of the indexes will be used.
I'm guessing based on your columns but it seems like the most common query will always be looking for is_active=1 and status='public'. If this isn't the case you might have to make some tweaks.
Firstly, get rid of the db_index=True on the status, is_active, and language fields, otherwise your database writes will be slowed unnecessarily.
Then you can formulate an index such as this:
class Meta:
indexes = [
models.Index(
fields=["is_active", "status", "language"],
name="idx_filtering",
)
]
This will help the database when you filter on all three columns at once. If you're ever filtering on only one of these columns however, you may want to keep the original db_index=True.
If you were using PostgreSQL, you could do one better:
class Meta:
indexes = [
models.Index(
fields=["is_active", "status", "language"],
name="idx_filtering",
condition=Q(is_active=True, status="public"),
)
This would reduce the size of the index to only those matching the Q(), making traversing it faster.
One other thing to note is that pagination using OFFSET is very slow once you get to higher offsets. If at all possible you should be using DRF's cursor pagination instead.
I have a Django model "Inspection" which has:
InspectionID (PK)
PartID
SiteID
Date
Comment
Report
Signiture
I want to be able to have a one to many relationship between the inspection ID and date. So one ID can have inspections at many dates. How would I do this? I currently have the following:
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
I thought about using models.ForeignKey but I really don't know how to implement that properly in this situation.
I want to be able to have a one to many relationship between the inspection ID and date.
You create an extra model, like:
class InspectionDate(models.Model):
inspection = models.ForeignKey(
Inspection,
on_delete=models.CASCADE,
related_name='inspectiondates'
)
date = models.DateField()
You thus can create InspectionDates for a given Inspection.
Or if you want to add extra data, it might be better to define an InspectionGroup model:
class InspectionGroup(models.Model):
pass
class Inspection(models.Model):
id = models.AutoField(primary_key=True, unique=True, db_column='InspectionId')
inspectiongroup = models.ForeignKey(InspectionGroup, on_delete=models.CASCADE, db_column='InspectionGroupId')
part = models.ForeignKey('Part', on_delete=models.CASCADE, db_column='PartId')
site = models.ForeignKey('Site', on_delete=models.CASCADE, db_column='SiteId')
date = models.DateField(db_column='Date')
comment = models.CharField(max_length=255, blank=True, db_column='CommentId')
report = models.FileField(upload_to='docs', null=True, blank=True, db_column='ReportId')
signiture = models.CharField(max_length=255, blank=True, db_column='Signature')
Note: the name of attributes are normally written in snake_case [wiki], not in PerlCase or camelCase.
you may store 'self Foriegnkey' as
class Inspection(models.Model):
InspectionID = models.IntegerField(primary_key=True, unique=True)
PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
Date = models.DateField(auto_now=False, auto_now_add=False)
Comment = models.CharField(max_length=255, blank=True)
Report = models.FileField(upload_to='docs', null=True, blank=True)
Signiture = models.CharField(max_length=255, blank=True)
inspection_id = models.ForeignKey('self', null=True, blank=True)