I have Category and Product Models. I have created 2 serializers for each model. When i want to add a new product i send this json: {"name":"name","price":1,"category":{"id":1}} but django gives error and says that i need to specify category name too. I have already given id so why do i have to give category name too (category that has id 1 already exists. I am trying to add new product to this category )?. If i make name field of category not required django doesn't give error. But when i want to add new category it doesn't give error if i don't specify name field in json. I want django to give "name required" error when i try to add new category but i don't want it to give error when i try to add new product. If i make category read_only it doesn't update category_id of product when i want to update a product.
class Product(models.Model):
name=models.CharField(max_length=32)
price=models.FloatField()
category=models.ForeignKey("Category",on_delete=models.CASCADE)
class Category(models.Model):
name=models.CharField(max_length=32)
class CategorySerializer(ModelSerializer):
class Meta:
model=Category
fields="__all__"
class ProductSerializer(ModelSerializer):
class Meta:
model=Product
fields="__all__"
category=CategorySerializer()
I have same issue.
My solution is:
class CategorySerializer(ModelSerializer):
class Meta:
model=Category
fields="__all__"
class ProductSerializer(ModelSerializer):
class Meta:
model=Product
fields="__all__"
category = CategorySerializer(read_only=True)
category_id = PKR(queryset=Category.objects.all(),
source="category",write_only=True)
in this way:
when you want add or update use category_id field to use exist category
if you want read serializer return category with all fields :)
Related
I have these two models :
class Project(models.Model):
name = models.CharField(max_length=50)
users = models.ManyToManyField(User)
class User(models.Model):
name = models.CharField(max_length=25)
I want to get a queryset containing all the Projects with a specific user in the 'users' ManyToManyField
I tried this : Project.objects.filter(users__contains=user), but it's not working
Does someone know how can I do it ?
if filtering with id:
Project.objects.filter(users=search_id)
if filtering with user name:
Project.objects.filter(users__name__icontains=search_input)
The app have 3 classes at model.py, and it was created a calculated field.
class Category(models.Model):
name = models.CharField(max_length=255)
class Asset(models.Model):
category = models.ForeignKey(Category, related_name='categories', on_delete=models.CASCADE)
class PortfolioAsset(models.Model):
asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
#property
def category(self):
return self.asset.category
I tried to add in the admin.py a list_filter:
class PortfolioAssetAdmin(admin.ModelAdmin):
list_display =('asset', 'category' )
list_filter =(('category', RelatedFieldListFilter),)
but i get the error message:
"PortfolioAsset has no field named category"
I think that is because category in PortfolioAsset is calculated, but don`t know how to solve that. Or if there is any better and working solution. Thanks
THE SOLUTION as Zufra said, change 'category' to 'asset__category':
list_filter =(('asset__category', RelatedFieldListFilter),)
Try asset__category. The PortfolioAsset model does not have a field named category as the error tells you. It has a foreign key to the Asset model and this model is the one with the field category.
As stated in this question
With Django REST Framework, a standard ModelSerializer will allow ForeignKey model relationships to be assigned or changed by POSTing an ID as an Integer.
I am attempting to update a reverse relationship of the following format:
class Lesson(models.Model):
name = models.TextField()
class Quiz(models.Model):
lesson = models.ForeignKey(Lesson, related_name='quizzes', null=True)
class LessonSerializer(serializers.ModelSerializer):
quizzes = serializers.PrimaryKeyRelatedField(queryset=Quiz.objects.all(), many=True, write_only=True)
class Meta:
model = Lesson
fields = ('quizzes')
When posting an update containing an array of quiz primary keys using LessonSerializer I get TypeError: 'Quiz' instance expected, got '1'.
Is it possible to assign or change a reverse relationship by POSTing an array of primary keys?
You don't need special field in a serializer, DRF serializers is smart enough to figure out related field from a fields value.
class LessonSerializer(serializers.ModelSerializer):
class Meta:
model = Lesson
fields = ('quizzes', 'name')
And you should pass list of ids, if there is only one value it should be a list anyway.
To solve this you need to create a Quiz instance first before you assign it to Lesson. Below's a small change to your code.
class Lesson(models.Model):
name = models.TextField()
class Quiz(models.Model):
lesson = models.ForeignKey(Lesson, related_name='quizzes', null=True)
class LessonSerializer(serializers.ModelSerializer):
quizzes = serializers.PrimaryKeyRelatedField(queryset=Quiz.objects.all(), many=True, write_only=True)
class Meta:
model = Lesson
fields = ('quizzes')
class QuizSerializer(serializers.ModelSerializer):
class Meta:
model = Quiz
fields = ('name')
Create POST request with with quiz then run your post again
I don't know if I am trying the impossible but I have HTML select option that comes from Django's forms.Form's queryset, States.objects.all().
Model:
class Countries(models.Model):
name = models.CharField(max_length=25)
Model:
class States(models.Model):
country_id = models.ForeignKey('Countries')
name = models.CharField(max_length=25)
Form:
class sign_up_form_school(forms.Form):
states = forms.ModelChoiceField(
queryset = States.objects.all(),
widget=forms.Select(attrs={
'class': states.country_id.name #is this POSSIBLE?
}))
I want each select option value to have different class as I have tried above but it returns error: name 'states' is not defined.
I think this answer will also be answer to your problem: Django form field choices, adding an attribute
You would just need to add class instead of title and change rendering a bit.
In the admin I want to use inline elements. I want category to display
the items it is related to.
But I get this error:
Exception at /admin/store/category/7/
<class 'store.models.Item'> has no ForeignKey to
<class 'store.models.Category'>
It's true, of-course, since I chose to use Category to point to the
items it has.
But, how can I get the admin to list in-line all the items that a
given Category has?
How can I get around this error?
CONTEXT:
class Category:
items=models.ManyToManyField(Item,through='Categoryhasitem')'
class Categoryhasitem(models.Model):
category = models.ForeignKey(Category, db_column='category')
item = models.ForeignKey(Item, db_column='item')
class Item(models.Model):
id = models.AutoField(primary_key=True)
This is my admin.py file.
class ItemInline(admin.TabularInline):
model=Item
class CategoryAdmin(admin.ModelAdmin):
inlines=[ItemInline,]
class ItemAdmin(admin.ModelAdmin):
pass
admin.site.register(Category, CategoryAdmin)
admin.site.register(Item, ItemAdmin)
The syntax is slightly different to display many-to-many relations using an inline.
class ItemInline(admin.TabularInline):
model = Category.items.through
class CategoryAdmin(admin.ModelAdmin):
inlines = [
ItemInline,
]
exclude = ('items',)
See the django admin docs for working with many-to-many models for more details.