I want all my models to have SlugField however it seems like its not a DRY principle for each and every model to have:
slug = models.SlugField(max_length=50)
I want to implement this as follows:
Base Model
class BaseModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=50, unique=True)
class Meta:
abstract = True
Company Model
class Company(BaseModel):
code = models.CharField(max_length=2, primary_key=True)
name = models.CharField(max_length=50)
class Meta:
verbose_name_plural = 'Companies'
def __str__(self):
return self.name
My other models will inherit BaseModel to have those fields inherited however, whenever I save new record, SlugField is empty. Anyone could enlighten me on this please!
Related
class EntityServiceSerializer(serializers.ModelSerializer):
class Meta:
model = Service
fields = '__all__'
class EntityCreateSerializer(serializers.ModelSerializer):
entity_service = EntityServiceSerializerThrough(read_only=True, source='serviceschedule_set', many=True)
class Meta:
model = Entity
fields = '__all__'
Model looks like this
class Entity(models.Model):
entity_service = models.ManyToManyField(Service, through='ServiceSchedule')
class ServiceSchedule(models.Model):
service = models.ForeignKey(Service, on_delete=models.CASCADE)
entity = models.ForeignKey(Entity, on_delete=models.CASCADE)
class Service(models.Model):
service_name = models.CharField(max_length=256, null=True)
slug = models.SlugField(max_length=128, unique=True, null=False, editable=False)
created_at = models.DateTimeField(editable=False, default=timezone.now)
updated_at = models.DateTimeField(default=timezone.now)
animal = models.ForeignKey(Animal, on_delete=models.CASCADE, default=None)
I have these serializers (there are more fields in entity model, but they're irrelevant since the only problem i have is with the Many2Many)
The thing is, when i put in body "entity_service": [1,2] in the response i still get = []. Even though i have in my database Services with pk 1,2,3,4.
Do you know how can i make it work?
Try it without a source as the field name is the same as the model field name
class EntityCreateSerializer(serializers.ModelSerializer):
entity_service = EntityServiceSerializerThrough(read_only=True, many=True)
class Meta:
model = Entity
fields = '__all__'
Get method working in browse-able api end-point but when i try to post using my end-point through browser, it fires me this error: (My serializers are nested)
This is my serializers.py and it is Nested serilizers
from rest_framework import serializers
from . models import Author, Article, Category, Organization
class OrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = '__all__'
class AuthorSerializer(serializers.ModelSerializer):
organization = OrganizationSerializer()
class Meta:
model = Author
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
category = CategorySerializer()
class Meta:
model = Article
fields = '__all__'
and this is my models.py
from django.db import models
import uuid
class Organization(models.Model):
organization_name = models.CharField(max_length=50)
contact = models.CharField(max_length=12, unique=True)
def __str__(self):
return self.organization_name
class Author(models.Model):
name = models.CharField(max_length=40)
detail = models.TextField()
organization = models.ForeignKey(Organization, on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Article(models.Model):
alias = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='author')
title = models.CharField(max_length=200)
body = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
and this is my views.py ( I am using APIView, not VIewset)
class ArticleDeleteUpdate(DestroyAPIView, UpdateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = 'alias'
and this is my urls.py
path('api/v1/article', views.ArticleListCreateGet.as_view(), name='article2'),
I worked 10 hours on it to fix the issue but i failed to fix it...
I am not getting whats wrong with this... this error ruined my sleep..
Can anyone help me please to fix this issue?
EDIT with the correct approach:
Sorry I just realized you are using ModelSerializers instead of Serializers.
You need to change from
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
category = CategorySerializer()
class Meta:
model = Article
fields = '__all__'
to
class ArticleSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField()
category = serializers.PrimaryKeyRelatedField()
class Meta:
model = Article
fields = '__all__'
And check the documentation of PrimaryKeyRelatedField as it includes some different options that might be interesting for the design of your API
https://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield
Most likely you will need the read_only=True option so you don't need to override any method
Original answer with a bit of explanation:
You are getting the error because the POST is trying to create the nested objects but your serializer does not override the .create() method so the serializer does not know how to handle the nested relationships.
Take a look on https://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations where you can get a grasp of what you need.
I have a SchoolClass with Members. I now want to make a Project that connects to some of the members. How do I do that?
class SchoolKlass(models.Model):
name = models.CharField(max_length=50)
members = models.ManyToManyField(UserProfile, blank=True,related_name='a')
class Meta:
verbose_name_plural = 'Klasser'
def __str__(self):
return self.user.username
class Project(models.Model):
members = models.ManyToManyField(SchoolKlass.members, blank=True)
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
schoolKlass = models.ForeignKey(SchoolKlass, on_delete=models.CASCADE)
As you can see, I want to access SchoolKlass.members inside the manytomany relationship of the Project model.
user circular import ..
class SchoolKlass(models.Model):
name = models.CharField(max_length=50)
members = models.ManyToManyField(UserProfile, blank=True,related_name='a')
class Meta:
verbose_name_plural = 'Klasser'
def __str__(self):
return self.user.username
class Project(models.Model):
members = models.ManyToManyField("SchoolKlass.members", blank=True)
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
schoolKlass = models.ForeignKey(SchoolKlass, on_delete=models.CASCADE)
provide the "appname.model" on relation filed. don't forget the quote,
I am using Django 2.0
I have two models
class Chapter(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
name = models.CharField(max_length=250, blank=False)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
class META:
verbose_name_plural = 'chapters'
db_table = 'chapters'
def __str__(self):
return self.name
class ChapterQuestion(models.Model):
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)
word = models.CharField(max_length=250)
definition = models.CharField(max_length=250)
class META:
verbose_name_plural = 'chapter questions'
db_table = 'chapter_questions'
def __str__(self):
return self.word
Since Each ChapterQuestion belongs to only one Chapter, I think it could be Many-to-one relation.
My admin.py contain only
admin.site.register(Chapter)
admin.site.register(ChapterQuestion)
I want to be able to add/edit multiple questions while creating/editing chapter using Django Admin.
But Django Admin is showing only chapter fields
Also, I want created_by column to be field automatically by logged in user and remove from form.
You need to use inline forms
class ChapterQuestionInline(admin.StackedInline):
model = ChapterQuestion
#admin.register(Chapter)
class ChapterAdmin(admin.ModelAdmin):
list_display = ["course","name","created_by"]
inlines = [ChapterQuestionInline]
I have a model like so...
class Driver(SupremeModel):
name = models.TextField(null=False, blank=False)
car = models.ForeignKey('Cars.Car', null=False, blank=False)
This model inherits from this abstract model...
class SupremeModel(models.Model):
creator = models.ForeignKey(User, related_name="%(class)s_creator", null=True, blank=True)
created = models.DateTimeField(null=True, blank=True)
deleted = models.BooleanField(default=False)
modified = models.DateTimeField(null=True,blank=True)
class Meta:
abstract = True
Then I have a ModelForm like so...
class DriverForm(SupremeModelForm):
class Meta(SupremeModelForm.Meta):
model = Driver
DriverForm inherits from this SupremeModelForm...
class SupremeModelForm(ModelForm):
class Meta:
exclude = ['created', 'creator', 'deleted', 'modified']
I want to make it so anytime anything that inherits from SupremeModel is queried for data, it automatically excludes all the data where deleted=True...
In this case, so that when I render the DriverModelForm, deleted entries of car are not displayed...
Is there anyway I can do this?
After some more research I discovered the solution is to override the default model manager of the abstract model... Like so...
class SupremeManager(models.Manager):
def get_queryset(self):
return super(SupremeManager, self).get_queryset().filter(deleted=False)
class SupremeModel(models.Model):
creator = models.ForeignKey(User, related_name="%(class)s_creator", null=True, blank=True)
created = models.DateTimeField(null=True, blank=True)
deleted = models.BooleanField(default=False)
modified = models.DateTimeField(null=True,blank=True)
objects = SupremeManager()
class Meta:
abstract = True