-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
Create table project sdg xref 66 #385
Create table project sdg xref 66 #385
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
Just resolved. Fang suggested deleting my local database. We do this by running the command: |
e9d5461
to
a3ff267
Compare
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.
Everything looks great!
- The PR was done with the correct branch.
- The issue was linked properly.
- The code changes were applied correctly.
Thank you for your valuable contribution! The documentation for the many-to-many relationship is really helpful for me personally.
@fyliu Del took a look at the PR and didn't have issues. We wanted to check with you to see if you had any additional comments or improvements. Otherwise, I'll squash and merge the PR and move on to other issues. |
a3ff267
to
817d368
Compare
The most recent force-push was an update to the documentation to reflect the unnecessary "through" field in the Project model for many-to-many relationships without additional fields on the "join table" between two 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.
Thanks for working though this new type of issue with related models! Great job documenting how to test it.
I think there's a problem with the api test where it always passes no matter what. Can you take a look?
app/core/tests/test_api.py
Outdated
proj_res = auth_client.get(PROJECT_URL) | ||
sdg_res = auth_client.get(SDG_URL) | ||
|
||
assert filter(lambda proj: str(proj["uuid"]) == str(project.pk), proj_res.data) |
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.
It looks like this is always going to pass since it's checking if the projects list contains the project model's pk.
I think you might have wanted to check if the projects list has a project that matches the sdg.projects models or one of them. I haven't given it much though on how to best test this.
This seems to work from my trial and error attempts:
assert proj_res.data[0]["sdgs"][0] == sdg.name
Possible missing API functionality
-
I was thinking "How would an API client assign an sdg to a project?" Do that API call and then check in the database to make sure it's really assigned. This might reveal that you need more code (in the serializer or somewhere) to help make that assignment.
-
Also, "How can an API client get the projects related to an sdg?" I found the
StringRelatedField
method as well, which returns the related project names. Maybe that's enough. It feels like we need something more than the name of the related sdg, like the pk instead, or as well. Suppose someone's doing an audit and wantsall the projects that are working on a specific sdg (sustainability goal)
. Maybe they want the project urls in addition to the names.
What do you think of these? I'm pretty sure the first one is a must, even though we don't have the explicit requirement to have it.
The generic thing to do is to return the pks of all the related objects so that a client can go look them up if they want the details like project urls.
We should bring this up at the meeting and push for some API design. With Django, we get the single table CRUD actions for cheap, but related data requires code for both assignment and retrieval in each direction. We don't need to implement them if they're not going to end up being called by a client.
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.
Thanks for catching this. Going forward, I'll test both cases, with and without the code changes to prevent this.
As for the 2 points you made, I agree that 1 is absolutely required and 2 has to be discussed more. It was something that came up while I was working on it, but it's not built into the docs or mandated in the task.
More specifically on point 2, I can imagine a case where the user may want to view an sdg and related projects on a single page. In that case you likely want more information than just the name, especially considering the project has many other fields. Although, I have no clue what the end user is doing as I haven't been to those meetings. I'm just implementing the models and relationships 😄.
It might take some research to see exactly how to implement more complex CRUD like this and document that, possibly a task itself. Then, creating tasks to actually implement it.
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.
Going back over what I did originally with the filter function: I did filter(lambda proj: str(proj["uuid"]) == str(project.pk), proj_res.data)
to make sure the test case doesn't assume I know how many projects are in the database at the time. The current change clearly still needs work, but it would make it more robust to changes if and when someone adds more projects in the pytest fixture. Let me know what you think.
I plan to implement the change suggested here:
assert proj_res.data[0]["sdgs"][0] == sdg.name
but this is after I find the correct sdg in the proj_res
. Maybe I'm overdoing or overthinking it, but I'm willing to work together on something that works. I'll push new changes so you can see what I'm thinking as a whole.
817d368
to
d24e691
Compare
Updated the test with suggested changes and more. The use of the filter function is removed in favor of the function here, for clarity. We should still come up with some agreement on what we want to test and how. I also updated the docs to reflect the changes. |
??? note "Updating models.py for many-to-many relationships" | ||
For adding many-to-many relationships with additional fields, such as `ended_on`, we can add | ||
|
||
```python title="app/core/tests/test_models.py" linenums="1" |
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 believe you meant core/models.py
instead of app/core/tests/test_models.py
.
|
||
For adding many-to-many relationships without additional fields, we can just add | ||
|
||
```python title="app/core/tests/test_models.py" linenums="1" |
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 core/models.py
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.
Thanks for fixing the api test!
I have just a few more nitpicks.
app/core/tests/test_api.py
Outdated
@@ -10,6 +10,7 @@ | |||
pytestmark = pytest.mark.django_db | |||
|
|||
USER_PERMISSIONS_URL = reverse("user-permission-list") | |||
PROJECT_URL = reverse("project-list") |
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.
It would be better to make the variable name plural like the other *-list
ones here.
app/core/tests/test_api.py
Outdated
|
||
|
||
def test_project_sdg_xref(auth_client, project, sdg, sdg1): | ||
def get_object(data, target_uuid): |
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.
Suggestion: I would change the "data" name into something like "objs" to make it clear it's expecting to be passed a list of objects.
app/core/tests/test_api.py
Outdated
assert test_proj["sdgs"][0] == sdg.name | ||
assert test_proj["sdgs"][1] == sdg1.name | ||
|
||
sdg.projects.add(project) |
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.
Isn't sdg and project already related from above?
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.
Yes, they should be related through the add statements from above. I removed that line now and confirmed that the GET request returns sdgs and the associated projects list.
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.
FYI: made the update and it complained about objs
as a name (something about clarifying it). My terminal output is gone now, so I don't know the exact error. Instead of objs
, I renamed to objects
and updated the changes I made in the docs as well.
app/core/tests/test_api.py
Outdated
test_proj = get_object(proj_res.data, project.uuid) | ||
assert test_proj is not None | ||
assert len(test_proj["sdgs"]) == 2 | ||
assert test_proj["sdgs"][1] != sdg.name |
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.
Maybe use the in
keyword for these asserts?
d24e691
to
09ddf2a
Compare
Made the changes suggested. I also tried to make corresponding updates to the One minor thing: I updated If we want to and it's necessary, this could be a good place to define how the CREATE, UPDATE, etc. request will implemented. Otherwise, more suggestions/comments are welcome on what is currently here. |
Thanks! Will look at it in the review.
I just realized this myself while reading throught @del9ra's PR. Looks like many of these made it through reviews. Yes, just change the one relevant to this issue and we can make another issue to fix the others.
Yes. I think we need to figure this part out. |
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.
Fantastic job! Well done @dmartin4820 Thank you.
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.
Thank you @dmartin4820. Looks great!
@fyliu it looks like you approved this - can you merge it or does something else need to be done? |
09ddf2a
to
0ba05bf
Compare
0ba05bf
to
9049e15
Compare
Just to explain what's happened in the above actions: I combined the code changes into one commit and left the documentation commit alone. THen I rebased it onto But I found out that Then I rebased the PR branch to |
Fixes #66
What changes did you make?
Todo