-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Created models for penn wrapped -- issue with pip files though #309
Conversation
request should look like this format: /wrapped/generate/?username=zharpaz&semester=2020A
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work so far! Django has a lot of intricacies but you're doing a good job navigating them so keep up the good work. Let me know if you have any questions about comments
|
||
|
||
class GlobalStat(models.Model): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to prefix with stat_
because it's a bit redundant
backend/wrapped/models.py
Outdated
|
||
|
||
# Add a new model for keys | ||
class UserStatKey(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep the names consistent and call this IndividualStatKey
backend/wrapped/models.py
Outdated
|
||
# Add a new model for keys | ||
class UserStatKey(models.Model): | ||
stat_key = models.CharField(max_length=50, null=False, blank=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here about stat_
prefix. Also make this the primary key
backend/wrapped/models.py
Outdated
# How to do this, using individual vs stat_key ? | ||
name = models.CharField(max_length=50, null=False, blank=False) | ||
template_path = models.CharField(max_length=50, null=False, blank=False) | ||
stat_locations = models.ManyToManyField(StatLocation, blank=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make this a through model see Gsr Group to User through GroupMembership as an example.
Also let's not make this "one or the other" model. Let's just make the administrator specify whether it would be individual or global through 2 seperate many to manys. It seems reasonable for the administrator to think about this anyway.
backend/wrapped/models.py
Outdated
class Page(models.Model): | ||
|
||
# How to do this, using individual vs stat_key ? | ||
name = models.CharField(max_length=50, null=False, blank=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name should be for internal use only. Also make it a primary key to ensure uniqueness.
backend/wrapped/views.py
Outdated
User = get_user_model() | ||
|
||
|
||
class GeneratePage(viewsets.ModelViewSet): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get the user through request.user
, and make sure you have to be authenticated to use this route. see our other views.
Also I don't think ModelViewSet is the right viewset to use here.
Also call this and associated urls Pages
. We're not really generating anything (generating implies side effects). We're just serializing data already in the db: we are returning Page
s filtered for the given semester, serialized in a particular way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually now that we are adding a Semester model, this should be thought of as returning data associated with 1 particular semester.
(And in the serializer for semester it turns it into a list of pages each of which can be serialized with the page serializer and so on...)
EDIT: actually I'm not partial to either, I think thinking about it as returning a list of pages seems fine too.
backend/wrapped/views.py
Outdated
pages = Page.objects.filter(semester=semester) | ||
|
||
# Serialize the data | ||
serializer = PageSerializer(pages, many=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the many=True here do
backend/wrapped/models.py
Outdated
@@ -0,0 +1,76 @@ | |||
from django.db import models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we talked about this before but I think we should actually make Semester a model again.
Reason I'm saying this is for admin page purposes, we can use inline models to manage all the pages for a particular semester at a time which seems like a clean way to do it.
We would make a semester model with 1 field, and make it many to many on pages.
We should think of a Page from now on as a page reusable across semesters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this here because we should probably use this later: https://django-admin-sortable2.readthedocs.io/en/latest/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you have to also make GlobalStatKey model
model = UserStatKey | ||
fields = ["stat_key"] | ||
|
||
class PageSerializer(serializers.ModelSerializer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not really using the other serializers since you're just serializing it and immediately reformatting it, so might as well not use it.
The way you should be thinking about serializers is that everytime you have a queryset and then you say to yourself "I wish I could have this queryset in this particular format" you should make a serializer.
Finished Models for wrapped and serializer working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking very promising! Next steps would be to clean up a lot of the dead code and get it ready to merge.
Most comments I left should be pretty quick and so let's just get this into a ready to merge state soon.
backend/wrapped/models.py
Outdated
|
||
|
||
# Why do we want time? Ask Vincent | ||
class Page(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets move this to the bottom so we don't have to specify the many to many models using strings
backend/wrapped/models.py
Outdated
|
||
|
||
# Why do we want time? Ask Vincent | ||
class Page(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also we need a duration field indicating how long this page should stay on screen for. This would be allowed to be empty
backend/wrapped/models.py
Outdated
|
||
|
||
class IndividualStatThrough(models.Model): | ||
IndividualStatKey = models.ForeignKey(IndividualStatKey,null=False, blank=False, default=None ,on_delete=models.CASCADE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason this is IndividualStatKey
instead of individual_stat_key
? same with others below
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this something more descriptive to its actual inherent meaning. Maybe IndividualStatPageField
(and the other GlobalStatPageField
from .models import Page, Semester | ||
from .serializers import PageSerializer | ||
from .serializers import SemesterSerializer | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that your doing it the django way, you can get away with writing even less code :)
e.g. something like this
class MyModelViewSet(viewsets.ReadOnlyModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note you don't need to pass in user in context. See how we access the user in serializers in our other code (e.g. Portal serializer)
model = Semester | ||
fields = ['semester', 'pages'] | ||
|
||
def get_pages(self, obj): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are manually writing what django can already do if you just hook up pages directly with the serializer. (See sublet serializers for example).
e.g.
amenities = serializers.PrimaryKeyRelatedField(
many=True, queryset=Amenity.objects.all(), required=False
)
images = SubletImageURLSerializer(many=True, required=False)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait sorry i think for this you need to manually pass the semester obj so yours is correct. But its kinda verbose why not just:
return PageSerializer(obj.pages.all(), many=True, context={'semester': obj}).data
backend/wrapped/serializers.py
Outdated
from .models import Page, IndividualStat, GlobalStat, IndividualStatThrough, GlobalStatThrough, Semester, User | ||
|
||
class IndividualStatSerializer(serializers.ModelSerializer): | ||
key = serializers.StringRelatedField() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use StringRelatedField because it relies on the __str__
which is ususally used for testing. Can you find a better one to use?
backend/wrapped/serializers.py
Outdated
user = self.context.get('user') | ||
semester = self.context.get('semester') | ||
|
||
individual_throughs = IndividualStatThrough.objects.filter(Page=obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You a bit too much manual serialization here. As an outline the following is a bit more reasonable:
- Serialize IndividualEntries to become a list of (field_name, value) pairs (using a serializer)
2.Serialize IndividualEntries to become a list of (field_name, value) pairs (using a serializer) - Combine into a dict and return.
Although this seems hard to describe over a code review. Maybe we can sit down and peer program for this part
backend/wrapped/serializers.py
Outdated
user = self.context.get('user') | ||
semester = self.context.get('semester') | ||
|
||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer filter(...).first() over get()
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #309 +/- ##
==========================================
- Coverage 90.59% 90.23% -0.36%
==========================================
Files 61 66 +5
Lines 2552 2684 +132
==========================================
+ Hits 2312 2422 +110
- Misses 240 262 +22 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Notes before merging:
- Merge in master to get rid of build errors
- Make sure everything is passing (except for test coverage)
- Note down the decrease in code coverage, you'll be responsible for bringing it up in ur next PR
No description provided.