How can i limit the number of objects we can save by with a condition and without a condition in django? - python-3.x

What is meant is, I want to save only one object with is_featured field true, if user tried to save another object with is_featured field true it needs to give a prompt, How can i accomplish that in django any idea?
class Event(BaseModel):
title = models.CharField(max_length=200)
time = models.TimeField()
date = models.DateField()
location = models.CharField(max_length=200)
location_url = models.URLField()
description = models.TextField()
is_featured = models.BooleanField(default=False)
image = VersatileImageField('Image', upload_to="web/events")
class Meta:
db_table = 'web_event'
verbose_name = ('Event')
verbose_name_plural = ('Event')
ordering = ('auto_id',)
def __str__(self):
return str(self.title)

You can add a check that if event is already created with is_featured true then you can return error else you can create instance
if Event.objects.filter(is_featured=True).exists():
return Response({"error":"Featured Event Already Exists"})
else:
Event.objects.create(**data)
```

Related

how do I get foreighkey of foreighkey without a loop in django?

It is a Django project, I am trying to create a wishlist (many-to-many will not help because I need DateTime of getting that wished item in the wishlist).
class Client(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField()
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, related_name="wishlist", on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
What I could do is only this:
wishlist = Client.objects.wishlist.select_related('product').all()
wish_products = [item.product for item in wishlist]
But I need something like this, without a loop but with a single SQL query and single line
wishlist = Client.objects.wishlist.product.all()
When I try to run this code I get an error AttributeError: 'RelatedManager' object has no attribute 'product'
You can .filter(…) [Django-doc] and then .order_by(…) [Django-doc] with:
Product.objects.filter(wishitem__client__user=my_user).order_by('wishitem__added_at')
You can make it more covenient to query by spanning a ManyToManyField with your WishItem:
class Client(models.Model):
# …
wishlist = models.ManyToManyField(
'Product',
through='WishItem'
)
class Product(models.Model):
# …
pass
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, related_name='wishitems', on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
then you can query with:
Product.objects.filter(client__user=my_user).order_by('wishitem__added_at')
It will also make querying for the .wishlist of the Client more covenient, of the Products where the .client_set is a manager that manages the Clients that have that Product on the wishlist.
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.
Many to many relationship will fix the problem you can add extra fields to your WishItem class you can try this :
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField()
class Client(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
WishProducts = models.ManyToManyField(Product,through='WishItem')
class WishItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)

update a field in all records of a table through a single form Django 4

I have the following model 'ARTICULO', which I have created and templates to edit it individually
# MODEL
class Articulo(models.Model):
id = models.AutoField(primary_key=True, verbose_name='codigo')
nombre = models.CharField(max_length=100, verbose_name='nombre elemento')
cantidad = models.PositiveSmallIntegerField(verbose_name='cantidad total')
cantidad_disponible = models.PositiveSmallIntegerField(verbose_name='cantidad disponible', default=5)
UNIDAD = 'und'
KILO = 'kg'
LITRO = 'L'
UNIDADES_BASE = [
(UNIDAD, 'unidades'),
(KILO, 'Kilogramos'),
(LITRO, 'litros'),
]
unidades = models.CharField(max_length=3, choices=UNIDADES_BASE, default=UNIDAD, verbose_name='unidad base')
area = models.CharField(max_length=100, verbose_name='tipo inventario', default='primaria')
persona_asignada = models.CharField(max_length=100, default='almacen', verbose_name='persona asignada')
def __str__(self):
trama = "articulo: " + self.nombre
return trama
#form to edit individually
class ArticuloEditarForm(forms.ModelForm):
class Meta:
model = Articulo
fields = ['nombre', 'cantidad', 'unidades']
# view for generate form of individual article
def editar(request, id):
articulo = Articulo.objects.get(id=id)
formulario = ArticuloEditarForm(request.POST or None, instance=articulo)
if formulario.is_valid() and request.POST:
formulario.save()
return redirect('inventario_inicio')
return render(request, 'inventario/editar.html', {'formulario': formulario})
but additionally I would like to create a page where I can perform an update of all the records of the table as a whole (as in the following image)
When clicking on the button, all records with the checkbox activated are updated in the database according to the value indicated in their text box.
From what I have investigated so far, I think I understand that I should use the form.Form class and not form.ModelForm in combination with formsets, but in the attempts I have made, I tried trying to define a form in this way, but it does not work for me.
class AsignarReservasArticulos(forms.Form):
articulos = Articulo.objects.all()
for x in articulos:
print(x)
participa = forms.BooleanField(label='')
My deduction tells me that I must generate the form that I show in my image in an integral way from my FORM or I must make a part in the form and another in the view.

How to pass a Count field to export field

I'm working on an export resource but I can't figure out how to pass this field from the view as a column in my export.
issues = Student.objects.annotate(Count('issue'))
def view_student(request):
issues = Student.objects.annotate(Count('issue'))
students = Student.objects.filter(school = request.user.school).order_by('year')
return render(request, 'view_student.html', {'students': students,'issues':issues})
This is how I tried it in the resoucrces.py but it shows no result
class ExportStudentsResource(resources.ModelResource):
books = fields.Field(attribute = 'books',column_name='books',widget= ForeignKeyWidget(Student, 'issue_count'))
class Meta:
model = Student
fields = ('student_id','name','year','klass','stream','books')
This field is not from any model so I just thought Student model could be habouring it. How can I make it work
You can override the .get_queryset(…) method [Django-doc] and annotate your Student objects with:
from django.db.models import Count
class ExportStudentsResource(resources.ModelResource):
books = fields.Field(
attribute='books',
column_name='books',
widget= ForeignKeyWidget(Student,'issue_count')
)
issues_count = fields.Field(attribute='issue_count')
def get_queryset(self):
return super().get_queryset().annotate(
issue_count=Count('issue')
)
class Meta:
model = Student
fields = ('student_id','name','year','klass','stream','books')

How can I join two child tables using Django Querset API?

I have a model with two child tables and one parent table. Here is the sample model classes.
# Stores list of unique category names
class Category(models.Model):
category = models.CharField(max_length=20, unique=True, validators=[MinLengthValidator(limit_value=5)])
name = models.CharField(max_length=20, validators=[MinLengthValidator(limit_value=8)])
# Parent class for the next two child classes
class DailyLog(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=100, validators=[MinLengthValidator(limit_value=8)])
code = models.CharField(max_length=4, validators=[MinLengthValidator(limit_value=3)])
suggested_values = models.CharField(max_length=100, null=True, blank=True)
# First child class defines display order for dailylog items
class DailyLogDisplayOrder(models.Model):
category_item = models.ForeignKey(DailyLog, on_delete=models.CASCADE)
display_order = models.PositiveIntegerField()
# Second Child class publishes dailylog on a daily bases
class DailyLogCheckList(models.Model):
daily_task = models.ForeignKey(DailyLog, on_delete=models.CASCADE)
publish_date = models.DateField(auto_now=True)
daily_task = DailyTaskCategoryManager() # Log manager to get records per category
How do I perform a cartesian product query? The last column comes from the first child table Dailylogdisplayorder. Here is the raw sql.
select daily_task_id, checklist.publish_date, disporder.display_order
from dailylogchecklist checklist, compliance_dailylogdisplayorder disporder
where checklist.daily_task_id = disporder.category_item_id and checklist.publish_date='2020-07-12'
I have tried using cursor.execute() method per Django documentation. However, I am not able to figure out how to return results in QuyerySet. And also looking for a better way to combine child columns using QuerySet. The return queryset is assigned to a formset.
class DailyTaskCategoryManager(models.Manager):
def with_displayorder(self, user):
from django.db import connection
dtrange = datetime.today().date()
with connection.cursor() as cursor:
cursor.execute("select daily_task_id, checklist.publish_date, disporder.display_order
from dailylogchecklist checklist, compliance_dailylogdisplayorder disporder
where checklist.daily_task_id = disporder.category_item_id and
checklist.publish_date=%s", [dtrange])
result_list = []
for row in cursor.fetchall():
p = self.model(id=row[0], daily_task_id=row[1], publish_date=row[2])
p.display_order = row[3]
result_list.append(p)
return result_list
I already answered to a similar question, You can use prefetch_related() to get the related child table data. Check this answer
https://stackoverflow.com/a/71571509/9561654

Django Haystack return related insances

Hi I´m using django with haystack search. I have one model for Events. Thats the model I'm doing the search on. I have a second model to count the hits/views for the Events. I wan't to return the number of hits for every event additional to the search results.
my view:
def event_search(request):
if request.method == 'POST':
query = str(request.POST['search'])
events = SearchQuerySet().auto_query(query).models(Event).order_by('date')
return render_to_response('event_search.html', {"events": events}, context_instance=RequestContext(request))
else:
return render_to_response('event_search.html', context_instance=RequestContext(request))
my models:
class Event(models.Model):
name = models.CharField(max_length = 70)
date = models.DateTimeField()
description = models.TextField()
active = models.BooleanField(default=True, editable=False)
featured = models.BooleanField(default=False)
class EventHitcount(models.Model):
hit = models.ForeignKey(Event)
ip = models.CharField(max_length=40)
session = models.CharField(max_length=40)
created = models.DateTimeField(default=datetime.datetime.now())
By giving the ForeignKey field a related name it can call and count the related objects.
class Foo(models.Model):
fk = models.ForeignKey(Event,related_name='foofk')
some more fields...
In the template:
{{ foo.foofk.count }}

Resources