I have pretty simple and obvious question that i am trying to search for a while now.
I have a model, Picture, that has foreign keys like created_by, Province, and City.
What I want is to get all model fields serialized to json.
Models.py:
class Picture(models.Model):
name = models.TextField("Title", max_length=10000, null=True, blank=True)
meta_data = models.TextField("meta_data", null=True, blank=True)
created_by = models.ForeignKey(User, related_name="created_by")
city = models.ForeignKey(City, null=True, blank=True)
pro = models.ForeignKey(Province, verbose_name="Province")
class Province(models.Model):
name = models.CharField(max_length=50)
pi_meta_data = models.TextField(null=True, blank=True)
intro = models.CharField(max_length=1000, null=True, blank=True)
description = models.TextField(max_length=10000, null=True, blank=True)
class City(models.Model):
name = models.CharField(max_length=50)
pi_meta_data = models.TextField(null=True, blank=True)
intro = models.CharField(max_length=1000, null=True, blank=True)
description = models.TextField(max_length=10000, null=True, blank=True)
You can use Django Rest Framework, and serialize models with ease.
Your model serializers would be:
class PicturesSerializer(serializers.ModelSerializer):
class Meta:
model = Picture
# Only including fields in this case to explicitly show that
# every field in the Pictures model is serialized. In the rest of
# the Serializes fields will be left out for brevity.
fields = ("name", "meta_data", "created_by", "city", "pro")
class ProvinceSerializer(serializers.ModelSerializer):
class Meta:
model = Province
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
Thats it. Seriously.
Everything is nicely packed into json for you, even if you change your models down the line.
But how easy is it to use the serialized data? A simple view using those serialized models would be:
class PicturesList(APIView):
"""
List all Pictures, or create a new Picture.
"""
def get(self, request, format=None):
pictures = Pictures.objects.all()
serializer = PicturesSerializer(pictures, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = PicturesSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
The documentation is literally amazing. They have a cool tutorial to get you started. They even have a sweet browseable api that lets you visually navigate through your api.
There is a "Django Full Serialization" module which is part of wadofstuff which can serialize related objects among other things. This answer https://stackoverflow.com/a/3753769/187729 has more info.
Related
I am using python 3.8 and django 4.0.6 + drf 3.13.1
There are models
class Profile(models.Model):
user='US'
manufacturer = 'MA'
admin='AD'
choice=[
(user, 'User'),
(manufacturer, 'Manufacturer'),
(admin, 'Admin')
]
user_company = models.CharField(max_length=2, choices=choice)
user = models.OneToOneField(User, on_delete=models.CASCADE)
last_request = models.JSONField(null=True)
class ProfileCompany(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.OneToOneField('Company', on_delete=models.CASCADE)
classCompany(models.Model):
id_company = models.IntegerField(null=True, unique=True)
Company = models.CharField(max_length=128)
Direction = models.CharField(max_length=512, blank=True)
Description = models.TextField(null=True, blank=True)
Categories = ArrayField(base_field=models.CharField(max_length=128), null=True, blank=True)
Products = ArrayField(base_field=models.CharField(max_length=128), null=True, blank=True)
Serializer
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model=Company
fields = '__all__'
The task is to make the pre-moderation of the creation and updating of companies by the admin.
Manufacturer creates a new company or updates data in it, this data is not visible to all users, but only to the admin. The admin accepts or rejects this data with a comment (in this case, the Manufacturer receives a message with this comment, corrects the data and sends the data again for moderation)
I could not connect django-moderation, because it is not suitable for REST.
Are there ready-made libraries or solutions?
I have created a project API in djangorestframework but I want to add a comments feature in it also. I was scratching my head thinking how can I do it but couldn't end up with a solution since I'm a beginner in djangorestframework.
here is my models.py:
class Project(models.Model):
title = models.CharField(max_length=300)
body = models.TextField(max_length=5000)
header_image = models.ImageField(default="default.jpg")
demo = models.URLField(null=True, blank=True)
code = models.URLField(null=True, blank=True)
and here is my serializers.py:
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = "__all__"
and here is my views.py:
#api_view(["GET"])
def getProjects(request):
project = models.Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
Please help me in showing how can I add a comments section to the project API
note: I don't want the comments API to be a different object instead it should be a nested object in the object of the project
As each project can have several comments, you should implement Comment model and make a FK between these two
models.py
...
class Comment(models.Model):
project = models.ForeignKey('Project', related_name='comments', on_delete=models.CASCADE)
text = models.TextField(null=False, blank=False)
... # Some other field if you want. like created_time, author, ...
Then you can have a nested serializer to get comments with project:
serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('text', ...)
class ProjectSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Project
fields = (..., 'comments')
I work on the voting system (vote up and vote down) and the functionality - follow.
I want it to be done well, because I don't have anyone to advise, I put the post and code here.
Follow function - it should show how many followers there are and who they are. I used here a m2m relation with the intermediate model Follower.
My question - is this the correct approach to the topic - using m2m with an intermediate model here?
Functionality vote up and vote down - it is supposed to show how many votes up and how many down and who voted down and who voted up.
My question is whether there is also OK here with the relation between m2m and the intermediate model Voter?
Code for follow feature:
class Post(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
title = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1024)
followers = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Follower', blank=True)
is_visible = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('posts:post_detail', kwargs={'pk': self.pk})
def number_of_followers(self):
return self.followers.count()
class Follower(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user
Code for vote up and vote down feature:
class Question(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
vote_up = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Voter', blank=True)
vote_down = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Voter', blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('qa:qa_detail', kwargs={'pk': self.id})
class Voter(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user
Now is working only follow feature but I want to make sure my approch is ok. Please and thanks for your help.
Currently there is nothing that differentiates the up_vote from the down_vote on the Question model so this will return the same query.
As a side note if you plan to add similar voting/following functionality to other models it may be worth considering whether this is a good use case for a Generic Relationship. This will create a polymorphic relationship and is DRY.
Here are the docs
generic relations
I tried to solve the problem and got stuck. The problem is that I have a post that I can follow. My problem is that I don't know how to add a tracking button. Should this be done by url, with a view? Or should it be rather as a method in the model?
My problem is also whether it is properly written in terms of models - using the intermediate model Follower?
Here is Post model and I would like to add followers here. I mean, everybody who is interested, can follow this post.
class Post(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
title = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1024)
followers = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Follower', blank=True)
is_visible = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('posts:post_detail', kwargs={'pk': self.pk})
def number_of_followers(self):
return self.followers.count()
Here is my manager for follower model:
class FollowerManager(models.Manager):
use_for_related_fields = True
def follow(self, user, pk):
post_object = get_object_or_404(Post, pk=pk)
if user.is_authenticated():
if user in post_object.followers.all():
Follower.objects.filter(post=post_object, user=user).delete()
else:
Follower.objects.create(post=post_object, user=user)
Here is Follower model:
class Follower(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = FollowerManager()
Interactions between a user's browser and the database can only be done via a URL and a view. That view might call a model method, but there is no possible way for the browser to call that method directly.
(Also I don't understand what you're doing in the manager. Why are you deleting followers if the user is authenticated? Note that will always be true, so the followers will always be deleted.)
I have a model that contains the newly added ListField class in DRF.
I am trying to store a List of strings so the output would look like so:
{
"hashtags":["something", "new"],
}
I'm pretty new to working with DRF but I seem to be having some trouble serializing the result. When I run the request I received a
HashField() is not JSON serializable error. Again I'm new to working with the the framework and Python in general but any suggestions, point in the right direction would be a help.
models.py
class HashField(serializers.ListField):
child = serializers.CharField(max_length=100)
class Mention(models.Model):
author = models.ForeignKey(User)
hashtags = HashField()
placename = models.CharField(max_length=140, default='SOME STRING')
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.placename
serializers.py
class MentionSerializer(serializers.ModelSerializer):
class Meta:
model = Mention
Django REST Framework has different kind of serializers, what you need here is a field serializer that validates a list type.
in serializers.py do as follow:
class MentionSerializer(serializers.ModelSerializer):
hashtags = serializers.ListField()
class Meta:
model = Mention