sei-ec-remote / project-4-issues

Open an issue to receive help on project 4
0 stars 0 forks source link

django querying between related fields #230

Closed mqpiffle closed 1 year ago

mqpiffle commented 1 year ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

django

What's the problem you're trying to solve?

adding context to a dashboard page when passing in a filter between two related models

Post any code you think might be relevant (one fenced block per file)

class BandDashboard(LoginRequiredMixin, TemplateView):
    # permission_required = 'main_app.remove_band_profile'
    model = BandProfile
    template_name = 'bands/dashboard.html'

    def get_context_data(self, **kwargs):
        band = BandProfile.objects.all()
        print(band)
        context = super().get_context_data(**kwargs)
        context['our_events'] = Event.objects.filter(bands=band.name)
        return context

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

image

What is your best guess as to the source of the problem?

not sure how to pass around field refs between views/models

What things have you already tried to solve the problem?

stockoverflow/internet/django docs

Paste a link to your repository here https://github.com/mqpiffle/Project-X-Gigstr

asands94 commented 1 year ago

What are you trying to filter?

mqpiffle commented 1 year ago

i'm trying to filter the events which include the logged in band as one of the bands in a MtM field

mqpiffle commented 1 year ago
class Event(models.Model):
    date = models.DateField('date', null=True, blank=True)
    time = models.TimeField('time', null=True, blank=True)
    ticket_price = models.DecimalField(max_digits=7, decimal_places=2)
    note = models.TextField(max_length=250)
    # MtM field for bands
    bands = models.ManyToManyField(BandProfile)
    venue = models.ForeignKey(VenueProfile, on_delete=models.CASCADE)

    class Meta:
        ordering = ['-date']

    def get_absolute_url(self):
        return reverse('events_detail', kwargs={'pk': self.pk})
class BandProfile(models.Model):
    name = models.CharField(max_length=50, null=True, blank=True, unique=True)
    # location should probably be it's own model, OtO 
    location = models.CharField(max_length=50, null=True, blank=True)
    website = models.CharField(max_length=50, null=True, blank=True)
    description = models.TextField(max_length=500, null=True, blank=True)
    image = models.CharField(max_length=50, null=True, blank=True)
    # hopefully tags can be implemented
    # genre = models.CharField(max_length=1, choices=GENRES, null=True, blank=True)
    genres = models.ManyToManyField(Genre)
    # mood = models.CharField(max_length=1, choices=MOODS, null=True, blank=True)
    moods = models.ManyToManyField(Mood)
    # link a profile to a user
    # i think i want one user to have only one profile (for now)
    # so maybe use a OtO relation instead?
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, null=True, blank=True)

    class Meta:
        permissions = (
            ("dashboard", "access band dashboard"),
       )

    def get_absolute_url(self):
        return reverse("band_detail", kwargs={"pk": self.pk})

    def __str__(self):
        return self.name
mqpiffle commented 1 year ago

any ideas??? am i asking the wrong question?

timmshinbone commented 1 year ago

What happens if you try to use context['our_events'] = Event.objects.filter(bands=band) instead of trying band.name like you have above?

Sorry for late reply, instructional staff are in a meeting.

mqpiffle commented 1 year ago

image

mqpiffle commented 1 year ago

i'm honestly not even sure if i'm using the correct url, i'm assuming the pk of that event is 1, since it's the first one i created. and as i recall from class, the pk of the first field is assigned 1.

mqpiffle commented 1 year ago

i also tried by changing the reverse() in the model to 'event_id'=self.id and changed the url path to match, and still no luck

timmshinbone commented 1 year ago

share the html you're using to navigate to the page that's throwing the error and your whole list of urls

mqpiffle commented 1 year ago
{% block content %}
    <h2>Our Dashboard</h2>
    <h3>{{ user.username }}</h3>
    {% comment %} left sidebar, band info {% endcomment %}
    <div>
        <h4>{{ band_profile.name }}</h4>
        {% comment %} etc {% endcomment %}
    </div>
    <div>
        {% for event in our_events %}
        <div>
            <p>{{ event.start_date_time }} - {{ event.end_date_time }}</p>
            {% for band in event.band_set.all %}
            <h5>{{ band.name }}</h5>
            {% endfor %}
            <h5>{{ event.venue }}</h5>
            <p>{{ event.ticket_price }}</p>
        </div>
    </div>
{% endblock %}
mqpiffle commented 1 year ago
from django.urls import path
from . import views 
from django.contrib.auth.views import LoginView

app_name = 'gigstr' 

urlpatterns = [
    path('', views.Home.as_view(), name='home'),
    path('accounts/signup/', views.signup, name='signup'),
    # PROFILE URLS
    # FANS
    path('fans/', views.FanList.as_view(), name='fans_index'),
    path('fans/<int:pk>/', views.FanProfileDetail.as_view(), name='fans_detail'),
    path('fans/create/', views.FanProfileCreate.as_view(), name='fans_create'),
    path('fans/<int:pk>/update/', views.FanProfileUpdate.as_view(), name='fans_update'),
    path('fans/<int:pk>/delete/', views.FanProfileDelete.as_view(), name='fans_delete'),
    # BANDS
    path('bands/', views.BandList.as_view(), name='bands_index'),
    path('bands/<int:pk>/', views.BandProfileDetail.as_view(), name='bands_detail'),
    path('bands/create/', views.BandProfileCreate.as_view(), name='bands_create'),
    path('bands/<int:pk>/update/', views.BandProfileUpdate.as_view(), name='bands_update'),
    path('bands/<int:pk>/delete/', views.BandProfileDelete.as_view(), name='bands_delete'),
    path('bands/<int:event_id>/dashboard/', views.BandDashboard.as_view(), name='bands_dashboard'),

    # VENUES
    path('venues/', views.VenueList.as_view(), name='venues_index'),
    path('venues/<int:pk>/', views.VenueProfileDetail.as_view(), name='venues_detail'),
    path('venues/create/', views.VenueProfileCreate.as_view(), name='venues_create'),
    path('venues/<int:pk>/update/', views.VenueProfileUpdate.as_view(), name='venues_update'),
    path('venues/<int:pk>/delete/', views.VenueProfileDelete.as_view(), name='venues_delete'),
    # EVENTS URLS
    path('events/', views.EventList.as_view(), name='events_index'),
    path('events/<int:pk>/', views.EventDetail.as_view(), name='events_detail'),
    path('events/create/', views.EventCreate.as_view(), name='events_create'),
    path('events/<int:pk>/update/', views.EventUpdate.as_view(), name='events_update'),
    path('events/<int:pk>/delete/', views.EventDelete.as_view(), name='events_delete'),
]
timmshinbone commented 1 year ago

is that html the one you're trying to render or the one with the link that's supposed to send to the page that's throwing the error?

mqpiffle commented 1 year ago

yes image

mqpiffle commented 1 year ago

oh sorry lmao...wait, are those two different urls you're asking about? i'm so confused. it's the html for the BandDashboard view. i don't have a link yet because i can't figure out how to redirect the user on login. this dashboard is where they ought to be sent.

timmshinbone commented 1 year ago

So, what action brings the user to that view? if it's a link they click on, show the html page that link exists on

mqpiffle commented 1 year ago

i don't have a link yet because i can't figure out how to redirect the user on login. this dashboard is where they ought to be sent. i'm just manually entering it for now

timmshinbone commented 1 year ago

ok, let me read over the urls real quick and get back to you in a minute

timmshinbone commented 1 year ago

share the view for band dashboard, what's the difference between the band dashboard and the band profile page?

mqpiffle commented 1 year ago
class BandDashboard(LoginRequiredMixin, TemplateView):
    # permission_required = 'main_app.remove_band_profile'
    model = BandProfile
    template_name = 'bands/dashboard.html'

    def get_context_data(self, **kwargs):
        band = BandProfile.objects.all()
        print(band)
        context = super().get_context_data(**kwargs)
        context['our_events'] = Event.objects.filter(bands=band)
        return context

The profile is just the basic info for the band. The dashboard is supposed to display their events, hearts, and other info (more as a strectch)

mqpiffle commented 1 year ago

do you think they should they just be the same thing?

timmshinbone commented 1 year ago

Yeah I think having all of that at least accessible from the band's show page would be the best course of action and probably a little easier to gather all that data in one place.

mqpiffle commented 1 year ago

hmm ok, let me try to puzzle a couple of things out from here

mqpiffle commented 1 year ago

i don't even know how to access the page

mqpiffle commented 1 year ago

image

timmshinbone commented 1 year ago

hmm, let me see the view for that

mqpiffle commented 1 year ago
class BandProfileDetail(LoginRequiredMixin, DetailView):
    # permission_required = 'main_app.view_band_profile'
    model = BandProfile
    template_name = 'bands/details.html'

    def get_context_data(self, **kwargs):
        band = BandProfile.objects.all()
        print(band)
        context = super().get_context_data(**kwargs)
        context['our_events'] = Event.objects.filter(bands=band)
        return context
mqpiffle commented 1 year ago

the permissions stopped working, too :/ nvm, i just had a typo on some of my views

timmshinbone commented 1 year ago

Doesn't your band detail view need to access a single band? I think that's the main source of issue:

band = BandProfile.objects.all()
print(band)

Should instead get the band by the pk

mqpiffle commented 1 year ago

? but I'm passing it an id in the url? that part is for listing the events - eventually. Or am I completely missing something?

mqpiffle commented 1 year ago

i even set up an index page just for s&g to try to list all the bands, then link to the details page, but it's a no-go. (i changed the reverse to band_id in the model)

{% extends 'base.html' %} 
{% block content %}
    <h3>All Bands</h3>
    {% for band in bands %}
        <p>{{ band.name }}</p>
        <a href="{% url 'gigstr:bands_detail' band.id %}">View</a>
    {% endfor %} 
{% endblock%}
timmshinbone commented 1 year ago

i'm saying the line that gets the bands is getting ALL the bands, not just one using that id you're passing to the url. Check the cat detail view in catcollector to see what I mean

mqpiffle commented 1 year ago

tried this to no avail. it looks like that's how i should reference the param in a CBV

def get_context_data(self, **kwargs):
        band = BandProfile.objects.get(id=self.kwargs['band_id'])
        print(band)
        context = super().get_context_data(**kwargs)
        context['our_events'] = Event.objects.filter(bands=band)
        context['band_profile'] = band
        return context
mqpiffle commented 1 year ago

i guess it's fixed