Saleor: Editing models and database structure by hand in Saleor

Created on 6 Apr 2020  路  12Comments  路  Source: mirumee/saleor

Hi all!

I recently forked Saleor 2.9 for a web app I am building for an art gallery that wants to display their products for sale as well as give their artists some publicity. I want to be able to have a bunch of cards (like "our team" components) that pull data from an Artists table on the back-end that stores information about the artists' names, emails, origins, etc, and then display it on the front-end. I am struggling to see how to modify the models/DB to create a new "Artists" table with name, email, info, and then to create a manyToMany-like relationship with the products I've populated in the DC, giving the products a "created by" attribute. There are tons of models files throughout the /dashboard directory, and even when I make changes to the core models to create an artist class, I don't know how to get it to show on the dashboard so artists can be created/modified from there.

In the end, I would like to make it so that the client (non-technical) can add artists and have them show up on the artists page I will make, somewhat like products show up on their pages (but obviously I cannot create a new category "Artist" as artists cannot have prices or shipping as they are people; and there are other attributes I would want like email that a product cannot have, either. They are also different to staff on the website, so I cannot use the "staff management" functionality.)

I looked at this question but Saleor structure has changed since then, and that was a relatively minor attributal change to an existing class (User) as opposed to the creation and integration of a new class. I'm surprised that despite extensively searching for anything on how to do something as straightforward as create a new model there is little documentation and discussion online; I must be missing something.

Please help :) Thank you!

stale

Most helpful comment

@tanishqkumar There is no docs on how to add a model since we use pure Django for that, there is no hidden knowledge here.

  • To create the Artists table you just create a class that inherits from django.db.models.model, then docker-compose run web python3 manage.py makemigration and docker-compose run web python3 manage.py migrate. That will create these tables in DB. Consider Artist model would possibly inherit from User model depending on your needs.
  • If you'd like an m2m relation with products so one artist will have a field "products" that points to a queryset of products assigned to him, just add a field on Products model like artist = models.ForeignKey(Artist, related_name="products") then of course make and run the migrations again.
    Entire app uses graphql to communicate via frontend-backend, just run dashboard or storefont and look in browser dev console to see how requests are made / build. graphql playground is also available at :8000 port.
  • when you have the models you should create mutations for managing your new objects. We use
    Graphene for that.
  • After you have mutations in place you can proceed with frontend work.

All 12 comments

@tanishqkumar There is no docs on how to add a model since we use pure Django for that, there is no hidden knowledge here.

  • To create the Artists table you just create a class that inherits from django.db.models.model, then docker-compose run web python3 manage.py makemigration and docker-compose run web python3 manage.py migrate. That will create these tables in DB. Consider Artist model would possibly inherit from User model depending on your needs.
  • If you'd like an m2m relation with products so one artist will have a field "products" that points to a queryset of products assigned to him, just add a field on Products model like artist = models.ForeignKey(Artist, related_name="products") then of course make and run the migrations again.
    Entire app uses graphql to communicate via frontend-backend, just run dashboard or storefont and look in browser dev console to see how requests are made / build. graphql playground is also available at :8000 port.
  • when you have the models you should create mutations for managing your new objects. We use
    Graphene for that.
  • After you have mutations in place you can proceed with frontend work.

Hi Tomasz--thanks for the response! When you say "proceed with frontend work", could you elaborate on how I would get all Artist-related info to show on the dashboard so it can be manipulated like everything else? I looked at forms.py in /dashboard, but that didn't seem to clear things up much either. And I assume I should just create the same type of mutations that other objects, like Products, have in Saleor within the creation of the new class?

Thank you :)

@tanishqkumar you would have to modify the dashboard code to your needs, entire dashboard (frontend) is a separate repository: saleor-dashboard - so you would need to create a separate view there that will allow staff user to manage Artist related things.
What do you mean by forms.py in /dashboard? Cannot see it in current code.

And backend-wise:
And I assume I should just create the same type of mutations that other objects, like Products, have in Saleor within the creation of the new class? - Yes, when writing mutations you can even inherit from our CRUD-like classes (ModelMutation and subclasses). On example how to create a new mutation for a model you can see my recent PR: https://github.com/mirumee/saleor/pull/5377/files There is a create invoice mutation written from scratch.

In general i've mentioned another repository here, so it's worth mentioning that saleor actually consists of three repositories (saleor, saleor-dashboard and saleor-storefront). First one is backend, 2nd is the "admin" dashboard and 3rd is the frontend users will use on your site to buy things. Don't know how you've set it up but for local development i recommend using saleor-platform which can set you up with these three quick and painless so you can jump into coding right away.

@tomaszszymanski129 Thanks so much for your super helpful comments, I've been learning the mutation structure in Saleor and how the data flow pipeline is setup between front and backend. I also migrated to 2.9 whereas I'd been using a legacy version before.

On an unrelated note but still to do with changing models and data flow, if I was interested in building a (different) app modifying Saleor to accommodate multiple merchants and their respective products, i.e. having a landing page where a user can choose to buy from Target OR CVS and THEN see THOSE products (just like they see products on the current home page)--would this just be a matter of having each merchant create a dashboard account and create products for their respective stores, and then a new landing page that routes the consumer to the merchant's store, accordingly, or does a change like this require a major revamp of many parts of the app?

I ask because I am unsure as to whether Saleor is built to offer one consumer goods from many different possible merchants, and have many different merchants manage those orders in their own respective dashboards, or is just a standard ecommerce solution for one company selling their own goods. I don't think I understand the model structure (I wasn't even sure if there would have to be any models changes to accommodate several merchants on one site?) well enough to know if making this change involves just what I mentioned and whether it's doable on the scale of a few days/weeks, or will take many months.

Thank you--Saleor's strong support for devs is making it one of my favorite platforms to build atop of!

@tanishqkumar Thanks for the kind words! Saleor currently supports the second model which is selling goods from one merchant. Changing it to support the multi-merchant approach is not on the current roadmap. It would be a significant change and I wouldn't rule out that it would be available at Saleor one day, but this is rather a distant future. For now, we want to make sure that the single-merchant approach works really well.

I see @maarcingebala One last thing I wanted to ask was about how you suggest a developer make timelines with Saleor, given its size and organizational structure, for example with the art gallery commerce site I'm building atop of it. Having only ever built smaller (non-production grade) apps from the ground up, building something atop a codebase like Saleor which has 600,000+ lines of code, hundreds of models and mutations passed through several files each is certainly new and challenging to get my head around.

So far, I have spent time setting up the project and adding the Artist model (as Tomasz discusses in the above posts), but I have yet to write graphQL mutations for the new artist model discussed in posts above, to change the design and layout of three pages on the front-end (incl. pulling some Artists data from the back-end to display), add Google Analytics and Stripe integrations as well as deploy the whole project on S3/Heroku (having never used either before). I just wanted to ask how long you think this would take a single developer given your understanding of Saleor's codebase. Of course it will vary greatly according to time and intensity put in, but I just wanted to gauge whether my (clueless) estimate of 2-4 weeks full time is anywhere near accurate given your understanding of Saleor architecture.

I appreciate this isn't really to do with Saleor's internal mechanisms and so you're going beyond your expectations if you give me some tips wrt this :) Thank you Marcin!

My rough estimate would be:

  • artist model and mutations/queries to manage it (and some tests) - 1 week if you know Saleor already, 2 weeks if you're not too familiar with Graphene/GraphQL.
  • Stripe integration is already there, so enabling it in your project shouldn't require much work.
  • Google Analytics - that's the frontend part and it may be as simple as adding one line with GA tracking ID
  • customizing the frontend - it depends on how much changes you have, you want to use the basic theme that comes with Saleor and just add new views it shouldn't be much work (if you're familiar with React).

So I guess the 4 weeks estimate sounds real.

You need to be aware that if you add new models and API directly in Saleor it may be more difficult to upgrade to new version of Saleor in the future, as you'll have to deal with merge conflicts. Another approach to avoid that is to create a separate small app that only does your specific logic and integrates with Saleor through webhooks/API.

https://docs.saleor.io/docs/next/developer/extending

That's so helpful--by the way, did you guys update the docs? When I read them a few weeks ago they were nowhere near as detailed for developers as they are now. So far I'd been trying to learn about the code and architecture basically by reading lots of the source code. The developer pages look super helpful! I'll look into extension architecture but also wanted to ask about deployment with Saleor.

I haven't used Heroku/S3 before, but how long do you think it would take to learn enough about S3/Docker to be able to deploy the app once built? I'll have to factor that into the timeline as my friends tell me deploying takes ages. Also--I'm curious about the way you have advocated extensibility, on the docs it implies that most people that use Saleor _don't_ modify the source code, or many that use it are not devs. I thought it was a tool solely for developers to extend/rewrite and that the _only_ thing you could do was to get a dev to change the source code.

Lastly, all of the docs refer to version: next. Does that mean some of the functionality described therein will not work with 2.9? If so, when does "next" come out and do we simply pull changes from master into our local copy?

The link that I've sent you is the new version of developer docs and it will be soon released as Saleor 2.10. "next" means that it's is not officially released and it's up-to-date with the master branch. You can switch to 2.9 docs which refer to the 2.9 release of Saleor (https://github.com/mirumee/saleor/releases).

I would say we were too focused on the code for a long time and the docs were a bit behind. Our goal for incoming sprints is to improve the docs with better documentation of the GraphQL API. Also, we want to add docs for saleor-storefront to explain how to use the SDK or customize the theme.

Heroku is probably the simplest way of deploying Saleor backend. As for the frontend (storefront) I haven't done this on Heroku - I personally use Netlify for my own project which is pretty simple to set up as well. Configuring S3 should be also fairly simple, I'm sure there is a lot of resources online about S3 itself. This document describes env variables that you'll have to configure in Heroku so that it uses S3 for media/static storage: https://docs.saleor.io/docs/next/developer/running-saleor/s3

Hi @maarcingebala I've spent the last week learning graphQL, graphene, and studying the data flow through the front-end to the API and backend. I had a few general questions that couldn't easily be answered looking through all the docs, previous StackOverflow posts, and Gitter/Spectrum posts--any thoughts would be much appreciated:

  • I'm a bit confused about how hooks are used in Saleor. In the Apollo Client tutorial, any and all mutations are used not by wrapping a component with a TypedMutation component, but by coupling data requirements _within the mutation itself_ by putting a useQuery or useMutationName hook _inside the mutation_ as opposed to wrapping it. Are all queries/mutations just defined in API and then used by wrapping components in Saleor? Maybe this uses a slightly older version of Apollo Client?
  • When trying to add basic functionality for a new model (Artists, as above posts), is it really necessarily to build out the wealth of files that each Saleor model has? Each model has hundreds of mutations (eg in ProductMutations of saleor/graphql/product/schema.py) and I was unsure of really how to go about making new mutations if all existing ones are this complex. Should I ignore the complexity of current mutations/queries and just write the createArtist into a new folder's schema.py as one would expect having just finished the graphene/graphQL tutorials?
  • Similarly, on the the front end, the dashboard's products/components has tons of little components it uses in the views where it allows the creation of a new product (eg LikeFilter, ImageSelectDialog). How could I get an approximation of the current createProduct view to make a create Artist view without writing all of these nuanced components myself?
  • And finally, a question on the createProduct process with the API. It's not clear to me how the Product object is actually created in mutations/products.py鈥攊n get_instance you鈥檙e fetching something then in def save() saving that instance? But how does this create something from scratch/match up to the def mutate convention in graphene?
  • More generally, how can I find the answer this type of question about graphQL and mutations鈥攁re there any docs/tips on how to create a mutation if you鈥檙e a graphQL noob and have only just finished the tutorials? The current dev docs only mention what apps/plugins are in extending Saleor and say nothing about how to extend mutations etc. Perhaps this is because it's pure graphQL--but still, how can someone understand the huge existing graphQL architecture without just reading all the source code?

Sorry for a long post, but I looked over everything you'd said and came up with these questions, and think they could be helpful for others in the future, too.

Thank you so much!

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

damianarechar picture damianarechar  路  3Comments

timuric picture timuric  路  3Comments

Ajorona picture Ajorona  路  3Comments

tanvirraj picture tanvirraj  路  3Comments

maltitco picture maltitco  路  3Comments