django-oscar integration error - python

I integration ecommerce into my code. And run into problem with Product. When i update me models.py with simple
class MyProduct(AbstractProduct):
pass
or even extend my Package model with AbstractProduct and try to create migrations the next error appears.
catalogue.Product.product_class: (fields.E304) Reverse accessor for 'Product.product_class' clashes with reverse accessor for 'Package.product_class'.
HINT: Add or change a related_name argument to the definition for 'Product.product_class' or 'Package.product_class'.
catalogue.Product.product_class: (fields.E305) Reverse query name for 'Product.product_class' clashes with reverse query name for 'Package.product_class'.
HINT: Add or change a related_name argument to the definition for 'Product.product_class' or 'Package.product_class'.
catalogue.ProductAttributeValue: (fields.E336) The model is used as an intermediate model by 'ckanwrap.Package.attributes', but it does not have a foreign key to 'Package' or 'ProductAttribute'.
catalogue.ProductCategory: (fields.E336) The model is used as an intermediate model by 'ckanwrap.Package.categories', but it does not have a foreign key to 'Package' or 'Category'.
catalogue.ProductRecommendation: (fields.E336) The model is used as an intermediate model by 'ckanwrap.Package.recommended_products', but it does not have a foreign key to 'Package' or 'Product'.
ckanwrap.Package.product_class: (fields.E304) Reverse accessor for 'Package.product_class' clashes with reverse accessor for 'Product.product_class'.
HINT: Add or change a related_name argument to the definition for 'Package.product_class' or 'Product.product_class'.
ckanwrap.Package.product_class: (fields.E305) Reverse query name for 'Package.product_class' clashes with reverse query name for 'Product.product_class'.
HINT: Add or change a related_name argument to the definition for 'Package.product_class' or 'Product.product_class'.
ckanwrap.Package.recommended_products: (fields.E335) The model is used as an intermediate model by 'ckanwrap.Package.recommended_products', but it has more than one foreign key to 'Product', which is ambiguous. You must specify which foreign key Django should use via the through_fields keyword argument.
HINT: If you want to create a recursive relationship, use ForeignKey("self", symmetrical=False, through="ProductRecommendation").
Any suggestions?

If anyone is still getting this problem, the solution is to create a class with the same name used by oscar. In this case, it would be Product.
from oscar.apps.catalogue.abstract_models import AbstractProduct
from django.db import models
class Product(AbstractProduct):
additional_field = models.CharField(max_length=200)
from oscar.apps.catalogue.models import *

Related

How can a model have multiple keys with the same type of models as values?

I'm making an application and I should make a Model which have 2 keys that saves models of the same type.
It's not easy to express in English so I will upload the image of the situation.
In Food Pair Model ( or we can call it table I think )
I want to refer Food Model But I wasn't able to use ForeignKey or ManyToManyField.
ERRORS:
food_test.FoodQuestion.left_food: (fields.E304) Reverse accessor for 'FoodQuestion.left_food' clashes with reverse accessor for 'FoodQuestion.right_food'.
HINT: Add or change a related_name argument to the definition for 'FoodQuestion.left_food' or 'FoodQuestion.right_food'.
food_test.FoodQuestion.right_food: (fields.E304) Reverse accessor for 'FoodQuestion.right_food' clashes with reverse accessor for 'FoodQuestion.left_food'.
HINT: Add or change a related_name argument to the definition for 'FoodQuestion.right_food' or 'FoodQuestion.left_food'.
I don't know what database relation to use in this case and how to make it.
What can I use for this case?
When you create a ForeignKey from one model to another Django will dynamically create a property on the model being referenced that will return a QuerySet with all objects that have the foreign key to that object
For example
class Foo(models.Model):
pass
class Bar(models.Model):
foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
foo = Foo.objects.create()
bar = Bar.objects.create(foo=foo)
foo.bar_set.all() # This will return a queryset containing foo
By default this property will be <model_name_lowercase>_set. In your case because you have 2 foreign keys from one model to the same model Django is trying to create the same property on the Food model for each foreign key.
To get around this issue you can specify the name of this property using related_name, if you set this to '+' no reverse relation will be made at all or give them unique names
class FoodQuestion(models.Model):
left_food = models.ForeignKey(Food, on_delete=models.CASCADE, related_name='+')
left_food = models.ForeignKey(Food, on_delete=models.CASCADE, related_name='+')
You must define a unique related_name for each ForeignKey field in your FoodPair model.
class FoodPair(models.Model):
first_food = models.ForeignKey(Food, related_name="first_food")
second_food = models.ForeignKey(Food, related_name="second_food")
what_i_buy = models.ForeignKey(Food, related_name="what_i_buy")
If related_name is not defined Django automatically sets it and when there is multiple ForeignKey fields pointing to the same model the names clash.

Export User model into different app

I have a project with one app, where user, their posts and other models are located. Now I want to separate User model and put it into different app, called users.
How should I do this correctly? And how do I use this model in the old app?
User model of the first app looks like this:
class User(AbstractUser):
class Meta:
permissions = (
('can_do_this', 'Permission1'),
('can_do_that', 'Permission2'),
...,
)
User model of the second (users)app looks like this:
class ExternalUser(AbstractUser):
class Meta:
permissions = (
('can_do_this', 'Permission1'),
('can_do_that', 'Permission2'),
...,
)
I've done django-admin startapp users and copy-pasted user's model code into created app models.py.
Then I tried makemigrations and it failed, showing:
SystemCheckError: System check identified some issues:
ERRORS:
photogal.User.groups: (fields.E304) Reverse accessor for 'User.groups'
clashes with reverse accessor for 'ExternalUser.groups'.
HINT: Add or change a related_name argument to the definition for
'User.groups' or 'ExternalUser.groups'.
photogal.User.user_permissions: (fields.E304) Reverse accessor for
'User.user_permissions' clashes with reverse accessor for
'ExternalUser.user_permissions'.
HINT: Add or change a related_name argument to the definition for
'User.user_permissions' or 'ExternalUser.user_permissions'.
users.ExternalUser.groups: (fields.E304) Reverse accessor for
'ExternalUser.groups' clashes with reverse accessor for 'User.groups'.
HINT: Add or change a related_name argument to the definition for
'ExternalUser.groups' or 'User.groups'.
users.ExternalUser.user_permissions: (fields.E304) Reverse accessor for
'ExternalUser.user_permissions' clashes with reverse accessor for
'User.user_permissions'.
HINT: Add or change a related_name argument to the definition for
'ExternalUser.user_permissions' or 'User.user_permissions'.
Adding related_name='+' to the old user model resulted in:
ERRORS:
<class 'django.contrib.auth.admin.UserAdmin'>: (admin.E020) The value of
'filter_horizontal[0]' must be a many-to-many field.
<class 'django.contrib.auth.admin.UserAdmin'>: (admin.E020) The value of
'filter_horizontal[1]' must be a many-to-many field.
Thanks!
Simply delete the old User model from the previous app, and put the new one in the new app, so that in the end you only have one User class that extends the AbstractUser class.
As for your second issue, try this.
I hope this helps.

Error using permission on custom User model

I am making a custom user model using AbstractUser in django.contrib.auth.models.
Everything was working fine until I wanted to make some changes in user_permissions of my SiteUser then Django gave an error that SiteUser has no attribute named user_permissions
Then I thought of extending PermissionMixin in django.contrib.auth.models to my SiteUser class to make changes in user_permissions but now It is throwing this error:
project.SiteUser.user_permissions: (fields.E304) Reverse accessor for 'SiteUser.user_permissions' clashes with reverse accessor for 'SiteUser.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'SiteUser.user_permissions' or 'SiteUser.user_permissions'.
project.SiteUser.user_permissions: (fields.E304) Reverse accessor for 'SiteUser.user_permissions' clashes with reverse accessor for 'SiteUser.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'SiteUser.user_permissions' or 'SiteUser.user_permissions'.
project.SiteUser.user_permissions: (fields.E331) Field specifies a many-to-many relation through model 'project.SiteUser_user_permissions', which has not been installed.
P.S. - I have used AUTH_USER_MODEL='project.CustomUser'

Django: related_name Reverse accessor

I have this model where InstitutePerson is a subclass of Person.
Person
InstitutePerson
Project
In Project:
participants_institite = models.ManyToManyField(InstitutePerson, blank = True, null = True)
participants_exterior = models.ManyToManyField(Person, blank = True, null = True)
I get an error:
Project.participants_institute: (fields.E304) Reverse accessor for 'Project.participants_institute' clashes with reverse accesor for 'Project.participants_exterior'.
I thought that related_name would solve the problem but after seeing some posts (related_name argument not working as expected in Django model?) I'm not sure how to proceed because of the inheritance among the classes.
Use related_name arg and define it manually
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name
If you have two M2M field with same type Django can't generate properties on target modela automatically.
if you are not intereset in reversed direction, you can simply ise
models.ManyToManyField(..., related_name='+r1')
models.ManyToManyField(..., related_name='+r2')

related_name argument not working as expected in Django model?

I recently got a ForeignKey clash in my Django model. I have the need to have two foreign keys (owner, assigned_to) ultimately pointing to the same model (a user).
From what I understand I need a related_name argument to solve that problem. So I did that:
assigned_to = models.ForeignKey(TaskUser, blank=True, null=True, related_name='user_assignment')
and
owner = models.ForeignKey(TaskUser, related_name="user_ownership"
But I'm still getting an error:
tasks.task: Accessor for field 'owner' clashes with related field 'TaskUser.user
_ownership'. Add a related_name argument to the definition for 'owner'.
tasks.task: Reverse query name for field 'owner' clashes with related field 'TaskUser.user_ownership'. Add a related_name argument to the definition for 'owner'.
Why am I still getting this error?
There is one catch, owner is in a super class (BaseWidget) and assigned_to is in a sub class (Task). Are there issues with using related_name in an inheritance relationship? Do I need to just override the inheritance of owner and redefine related_name in the sub class instead? I'd appreciate any help!
If you have ForeignKey relationships in an abstract base class every class inheriting from it will have this relationship. As a result of this you must not 'hardcode' its related_name, because all sub classes will try to create the same accessor on the realted class (TaskUser in this case).
You should better do something like:
owner = models.ForeignKey(TaskUser, related_name="%(app_label)s_%(class)s_ownership")
See the django docs on this.
If you are using related_name in abstract base class you need to use a '%(app_label)s' and '%(class)s' in it.
Its mentioned in django doc
Be careful with related_name

Categories

Resources