Editing models and extending database structure in Saleor - python

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.
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!

The django way to create new models, (and Saleor´s backend is django based) is:
You should create a new app on your store backend (the django part of saleor) with:
$ python manage.py startapp artist
Create your Artist model, with all the fields you want such as email, etc... in the file: artist/models.py.
Modify the Product model in the file product/models.py by importing the Artist models and adding a ForeignKey (for example) relationship to it.
Register the new artist app in your settings.py's "INSTALLED_APPS".
Run python manage.py makemigrations... (Check they include your changes to models)
Run python manage.py migrate.
That should be it. 'less I`m forgeting something, in which case, please post back when you have moved forward with this.
Notes:
You may want to back up your DB first.
Also when applying these migrations, django will ask you for a placeholder value for products which where in your DB before Product had an Artist field.
References:
django models
django migrations

Related

Additional auth tables when extending Djangos AbstractUser

I am new to Django and discovered something I do not quite understand: I extended the default user class of django auth with a custom field to look like this:
class User(AbstractUser):
business_entity = models.ForeignKey('BusinessEntity', on_delete=models.PROTECT)
In the settings file, I also added the needed AUTH_USER_MODEL = 'core.User' since my new user model is located in the core app. Works fine so far.
After applying all migrations (even after wiping the database and reapplying), I, however, am left with a few additional tables that I did not want to create and that seem not to be used by Django's auth app:
Tables created after migration
As you can see there are from the auth app: auth_group, auth_group_permissions and auth_permissions as well as from core app: core_user_groups, core_user_user_permissions.
I searched quite a while - maybe with the wrong keywords? - but I am not able to figure out if I need all those tables and - especially - what the additional core tables are used for. Can you shed some light on this?
Thank you very much!
I am quite sure those are the tables that django uses to store permissions and you shouldn't delete them. For instance, when you make a superuser (an admin), django knows that only he/she can access the /admin page. This knowledge comes from permissions stored in those tables.
If you are not using those tables chances are they only occupy a minimum amount of space (according to the link below, only 4 permissions are added by default) and you shouldn't worry about them. That said, knowing how to manage permissions well can help a lot depending on your project.
More info about permissions can be seen here.

Flask - User to Profile Relationships

I'm working with Flask-restplus and I am at a point where I would like to associate each User in my user model to a type of profile, where each user can be associated with one or many profile types. I'm wondering how you guys would go about this. So far, here's what I'm thinking/planning to do. NOTE: I'm not very experienced in web development, so there's a chance I don't know the best way to accomplish this.
Step 1: Create a one-to-many (clients need to also be employees, see below) field (profile_types) relating to a static table that just lists all possible profile options. EXAMPLE:
PK PROFILE TYPE
1 provider
2 employee
3 client
.....
The idea here is to track different information and allow for different views/endpoints for users who are tied to certain profile types. Example, employees would provide a valid login authentication and be directed to page A while a client would be directed to page B, etc. We're also planning on collecting different data points within each profile model.
So an instance of a user might look like this, user1.profile == [client, employee'].
NOTE: This is more important for data collection (ie age of employee, start date, etc) than it is for creating directives based on permissions.
Step 2: Upon creating the new user, a signal fires off the creation of a profile based on the profile_types supplied to the user instance. I've used signals with django in the past, is there a signal library for Flask?
Step 3: An empty profile instance(s) now exists for that user. It will be up to a superuser to upload data in bulk or manually fill out profile information.
Is this a sensible way to go about this? My other though is to create a bunch of Boolean fields in the User model is_provider, is_employee, is_client, etc. All fields that are True get assigned a profile instance. What's the best way to go about this?
Thanks everyone!
Seeing that are you try to validate multiple profile types, you may use
if user.profile_type in ['employee', 'client']
Now, if you want to add an super user I think you can use this
if user.profile_type in ['employee', 'client'] and user.profile_type == 'superuser'
Now, you relationship is more like 'many-to-many', because you are saying that an client also needs to be an employee, if you mean that some endpoints needs to be accessible for employees and clients, then you need to use a 'many-to-one' relationship (an Stackoverflow question which explains what is that)
For your instances, there is Flask Marshmallow, which has an amazing compatibility with Flask SQLAlchemy if you are using an database, but Flask Marshmallow can work alone.

django request distant database

I'm trying to request, in a django project "FIRST", an existing database for an other django project "SECOND" witch are deployed in two differents machines.
I need to get in app 1 the values of an attribute's modele in app5 (as explained below).
I've search "how django requests distant database" but i didn't found an answer to my question
Thank you,
Machine 1 (192.xxx.xx.xx) :
----- project FIRST
------APP1
------APP2
Machine 2 (192.yyy.yy.yy) :
----- project SECOND
------APP3
------APP4
------APP5
You need a RESTful API.
A big topic, and I actually just answered it for another person.
I suggest you check it out here.
Once you make your API's, you can make some admin actions that go fetch the data, and populate your new database with the values of the old.
At least that's one way of doing it.
I've used dirkgroten's solution. It works for me on test plateform (with docker's container).
The steps I folow :
create à new django app with the same name that the App5 in project "FIRST".
copy, in the models.py (e.i: FIRST/app5/models.py), only tables and fields that I need to get from SECOND/app5.models.py
add the new 'app5' in INSTALLED_APP in the FIRST/settings.py
add, in the DATABASES of the FIRST/settings.py, the definition of parameters witch let the project connect to the distant database.
add the route database in the routers.py file
Don't forget to import the models of the new app5 in app1
note that if your tables hav other tables debendencies from the models.py you have to add them too in the new models.py
I gess that I haven't forget any other step
Thank's to every one for your responses
(PS: SORRY FOR MY BAD ENGLISH)

How to add to google app engine flask website the user registration ability if it wasn't scheduled in application architecture

I created website-app for myself and it become really useful and many peoples wont also use it. But user management was not scheduled in application architecture. Is there any way to easy add user registration so each user would have his own google database tables but with same name?
example of one "table":
class Settings(db.Model):
email = db.StringProperty()
link = db.LinkProperty()
rating = db.StringProperty()
How can I separate data from this "table" between different users? I search for some kind of wrapper so I don't need to change current architecture.
You have to remember there is no concept of tables with the datastore so you can't have a separate set of tables for each user as such.
You have a few choices, the two I would investigate are
create a separate app with the existing code base and each user runs their own site. You may not need to do any code changes at all
If you want complete separation of data for each user in a single app then look at namespaces (thats how multi-tenancy is normally implemented.)
However you haven't really provided a clear definition of how you want to separate the users etc.. so there a probably other approaches you can take.
Short of having a copy of the database for each user; you'll have to implement some code changes.
The easiest one you can do is add a foreign key to your data tables that points to your user table; then you filter all records based on this foreign key.
Once you have that change, you can write a view decorator that will automatically filter the records for you.

Do I need to create a separate class in my models.py when using the django.contrib.auth.models import user?

The import statement import the needed parts. but is the "user" class already made when you put that into your installed apps? or do you still need to clarify in models.py in order to make the table in the db? or can someone expand on how to use django users and sessions? I'm looking over the django docs right now and they all just go over how to use the thing once. they never put the code in a syntax where users are going to be the ones using the code through a browser and not you through a python shell.
All installed apps can contribute to the database schema. django.contrib.auth.models contributes, among others, the auth_user table behind the django.contrib.auth.models.User model, therefore you do not have to worry about recreating it unless you have a specific reason to do so.
There's a number of things going on here. As you're aware, Django comes with a number of "contrib" packages that can be used in your app. You "activate" these by putting them into your INSTALLED_APPS.
When you run python manage.py syncdb, Django parse the models.py files of every app in INSTALLED_APPS and creates the associated tables in your database. So, once you have added django.contrib.auth to your INSTALLED_APPS and ran syncdb, the tables for User and Group are there and ready to be used.
Now, if you want to use these models in your other apps, you can import them, as you mention, with something like from django.contrib.auth.models import User. You can then do something like create a ForeignKey, OneToOneField or ManyToManyField on one of your models to the User model. When you do this, no tables are created (with the exception of ManyToManyField; more on that in a bit). The same table is always used for User, just as for any of your own models that you might create relationships between.
ManyToManyFields are slightly different in that an intermediary table is created (often called a "join table") that links both sides of the relationship together. However, this is purely for the purposes of that one particular relationship -- nothing about the actual User table is different or changed in any way.
The point is that one table is created for User and this same table is used to store all Users no matter what context they were created in. You can import User into any and all of your apps, create as many and as varied relationships as you like and nothing really changes as far as User is concerned.
If the table name or something else does not fit in your needs you can always just extend the User model.
from django.contrib.auth.models import User
class Employee(User):
...
Any class extending Model class in models.py contributes to database schema. That means, django search your (and also django core) model.py files and looks for any class that extends Model like:
some models.py
class SomeModel(Model):
...
...
class Otherthing(Model):
...
that is also applies for django core code files. Since all Database tables named using application label and model name, database ables created by django also have that...
For example,
from django.contrib.auth.models import User
If you track file hierarchy django -> contrib -> auth and open models.py file, you will see related model. Ther are also other Model classes in here, like Permission and Group models.
Since these models are under auth application, database tables are auth_user, auth_perission and auth_group
When you run manage.py syncdb command for the first time, django will create these tables...

Categories

Resources