How to show list of available cars in list view? - django-models

I am having a car model is_available =models.booleanfield(default =False)
Can anyone tell me the query to show only available cars in class list view ?

The easiest would be to override the get_queryset method of the ListView. The query itself is straightforward:
class CarListView(ListView):
# ...
model = Car
# ...
def get_queryset(self):
qs = super(CarListView, self).get_queryset()
qs = qs.filter(is_available=True)
return qs

Related

Django Rest returning related items for each item

I was trying to find answer in similiar questions, but none was meeting my expectations.
I have 2 models:
class Artist(models.Model):
name = models.CharField(max_length=255)
music_type = models.CharField(max_lenght=50)
def __str__(self):
return self.name
class Event(models.Model):
event_name = models.CharField(max_length=255)
...
artists = models.ManyToManyField(Artist)
def __str__(self):
return self.event_name
I also have serializers.py file:
class EventSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields = '__all__'
class ArtistSerializer(serializers.ModelSerializer):
events = EventSerializer(source='event_set', many=True)
class Meta:
model = Artist
fields ='__all__'
The event in ArtistSerializer allows me to return all events where artist takes part.
Now for each artist I would like to get list of all artists if they ever were taking part in the same event.
For example I have 5 Artists (A1...A5) and 3 Events (E1...E3)
In Event 1: [A1,A3]
In Event 2: [A3,A4,A5,A2]
In Event 3: [A2, A3]
So for A3 I would like to get list [A1,A4,A5,A2]
For A1: [A3]
For A2: [A3,A4,A5]
Unfortunately I have huge problem to create this query as SQL-query and ORM mechanism looks more complicated in this situation. Can somebody help me with this problem or give hints how to solve this?
If it's needed I'm gonna share more code
You can query the through model to get the artists related to an event. This is the intermediate model which django will have created to make that M2M relationship.
Where you have a ManyToManyField it has an attribute of through which is the M2M model.
So from your event model you could do something like Event.artists.through.objects.all() and you'd see all the instances in your M2M model.
So to find out the artists which are linked to a given event you could query that same table;
Event.artists.through.objects.filter(event_id=1).select_related('artist')
This would then return all the objects in the M2M which belong to Event 1. You could then get the artists from there, or just grab the artist IDs Event.artists.through.objects.filter(event_id=1).values_list('artist_id, flat=True)
Given the scenario in your comment...
If you have an artist, then you can run a query to get the events they've been in, and then run another query with those event ids. In that second query you are then looking to get the artist ids that aren't the current artist you're already looking at.
# First get the events that the current artist has been in
event_ids = Event.artists.through.objects.filter(artist_id=1).values_list('event_id, flat=True)
# Then get the other artists who have been in the same events
other_artist_ids = Event.artists.through.objects.filter(event_id__in =event_ids).exclude(artist_id=1).values_list('artist_id, flat=True)
# or the full instances
other_artists = Event.artists.through.objects.filter(event_id__in =event_ids).exclude(artist_id=1).select_related('artist')

How to give user option to select a wagtail collection of images in page?

I am looking for a way to show a list of wagtail collection as a field in a page (just like it showing when you upload an image). A user can select a collection and I can programmatically filter the images to the selected collection. I am still new to wagtail and I am not sure how should I implement this in code.
Thank you in advance for your help.
So there's a couple ways you can do this. The first, and probably the least-ideal way is to register Collection as a snippet and use a SnippetChooserPanel.
"""Register Collection snippet."""
from wagtail.snippets.models import register_snippet
from wagtail.core.models import Collection
# Register Collections as Snippets so we can use the SnippetChooserPanel to select a collection
register_snippet(Collection)
And then in your model you can use a SnippetChooserPanel, like so (note, this is all untested code)
from django.db import models
from wagtail.core.models import Page
class CustomPage(Page):
# ...
collection = models.ForeignKey(
'wagtailcore.Collection',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
content_panels = Page.content_panels + [
# ...
SnippetChooserPanel('collection'),
]
#gasman's comment on the answer has a link to another solution that's much more elegant than mine.
I've managed to do this using wagtail-generic-chooser just following the instructions on the README.md, and using wagtail core Collection model instead of People.
Aug 2022 - Wagtail 2.15.5 - display Wagtail hierarchical collection
from wagtail.admin.templatetags.wagtailadmin_tags import format_collection
class Meeting(models.Model):
COLLECTION_CHOICES = []
for c in Collection.objects.all():
COLLECTION_CHOICES.append((c.id, format_collection(c)))
title = models.CharField(max_length=100)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, help_text="Choose the 'Collection' folder for the meeting's related documents", choices=COLLECTION_CHOICES)
Edit: If you add a new collection to collections and go back the this Meeting model the new collection will not be in the list. As the COLLECTION_CHOICES is only created once for optimization. If you want a dynamic collection choice you need to make a custom form on top of your model e.g.
from wagtail.admin.forms import WagtailAdminModelForm
class MeetingAdminForm(WagtailAdminModelForm):
# This below field will be automatically added to the Meeting panel fields
meeting_collection = forms.ChoiceField()
def __init__(self, *args, **kwargs):
super(MeetingAdminForm, self).__init__(*args, **kwargs)
self.fields['meeting_collection'] = forms.ChoiceField(
initial=self.instance.collection_id,
choices=[(c.id, format_collection(c)) for c in Collection.objects.all()]
)
def save(self, commit=True):
instance = super().save(commit=False)
instance.collection_id = self.cleaned_data['meeting_collection']
if commit:
instance.save()
return instance
class Meeting(models.Model):
base_form_class = MeetingAdminForm
class Meta:
""" Meta options """
ordering = ['title']
title = models.CharField(max_length=100)
meeting_datetime = models.DateTimeField()
location = models.TextField(null=True)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, help_text="Choose the 'Collection' folder for the meeting's agenda, minutes and related documents")
committee = models.ForeignKey(Committee, on_delete=models.CASCADE)
panels = [
FieldPanel('title'),
FieldPanel('meeting_datetime'),
FieldPanel('location'),
FieldPanel('meeting_collection'),
FieldPanel('committee'),
]

Django: how to save additional fields in a database?

I have a class in models.py:
class Person(AbstractUser):
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
It`s related to AbstractUser from contrib/models.py
I`ve made a class that lets make additional fields to it.
class ExtraTextField(models.Model):
add = models.ForeignKey(Person)
new_field_text = models.TextField(max_length=200, verbose_name='content')
def __unicode__(self):
return u'%s' % (self.new_field_text)
class AddText(admin.StackedInline):
model = ExtraTextField
extra = 0
class AdminForm(admin.ModelAdmin):
inlines = [AddText]
As you see, amount of fields is not defined, so I can`t just put them into class Person. But as a logical continuing, these additional fields are not saved in the database. Please, help, how can I solve this problem?

Filter possible choices for ForeignKey

Welcome,
I have some problem with limiting choices related with ForeignKey. Below I'm attaching fragment of my code (models.py):
class Car(models.Model):
name = models.CharField(max_length=50)
....
class Driver(models.Model):
name = models.CharField(max_length=50)
car = models.ForeignKey(Car)
....
class CarForm(ModelForm):
class Meta:
model = Car
class DriverForm(ModelForm):
def __init__(self, *args, **kwargs):
super (DriverForm,self).__init__(*args, **kwargs)
self.fileds['car'].queryset = Car.objects.filter(???_1_???)
class Meta:
model = Driver
Could anybody give me some advices how should be defined ???1??? to restrict available Car objects only to these which aren't assign to any Driver?
First of all, you may want to consider changing the relationship between Car and Driver to a OneToOneField rather than a ForeignKey if each Car can always only have a single Driver.
However, if you just want to restrict the choices in the form, your queryset needs to be something like:
from django.db.models import Count
self.fields['car'].queryset = Car.objects.annotate(num_drivers=Count('driver')).filter(num_drivers=0)

Annotate and Aggregate function in django

In django I have the following tables and am trying to count the number of votes by item.
class Votes(models.Model):
user = models.ForeignKey(User)
item = models.ForeignKey(Item)
class Item(models.Model):
name = models.CharField()
description = models.TextField()
I have the following queryset
queryset = Votes.objects.values('item__name').annotate(Count('item'))
that returns a list with item name and view count but not the item object. How can I set it up so that the object is returned instead of just the string value? I have been messing around with Manager and Queryset methods, that the right track? Any advice would be appreciated.
You can try something this:
queryset = Votes.values.annotate(t_count=Count('item'))
To get the count value of first Vote object:
queryset[0].t_count
or to get Item object:
Item.objects.annotate(i_count=Count('votes'))

Resources