models.py
address_choices = (("home":"Home"),("shop", "Shop"))
class Address(models.Model):
address_type = models.CharField(max_length=128, choices=address_choices)
location = models.CharField(max_length=128)
forms.py
class AddressForm(forms.ModelForm):
class Meta:
model = Address
views.py
home_address = AddressForm(prefix="shop")
shop_address = AddressForm(prefix="home")
can i use prefix in serializers just like that i used in forms above
serializers.py
class AddressSerializers(serializers.ModelSerializer):
class Meta:
model = Address
views.py
home_serializer = AddressSerializers(prefix="home")
shop_serializer = AddressSerializers(prefix="shop")
As you have the current model Address it's enough to have one serializer for that. You can specify {'address_type': 'home'} or {'address_type': 'shop'} when using that. If you want to have multiple addresses (bulk creation) you should use a ListSerializer or the many=True parameter if you used it inside other related serializer.
Related
i am reciving a "value error"
because of "ModelForm has no model class specified."
i tried to check the : models.py forms.py and views.py but all looks pretty good for me
views.py :
class CreatePostView(LoginRequiredMixin,CreateView):
login_url='/login/'
redirect_field_name='Myblog/post_detail.html'
form_class = PostForm
model = Post
models.py:
class Post(models.Model):
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True,null=True)
forms.py:
class PostForm(ModelForm):
class meta:
model = Post
fields = ('author','title','text')
from app.urls.py
url(r'^post/new/$',views.CreatePostView.as_view(),name='post_new'),
Meta is with an uppercase, according to PEP-8 the names of classes all start with an uppercase. In your form, you should write:
# app/forms.py
class PostForm(ModelForm):
class Meta:
model = Post
fields = ('author','title','text')
Since you wrote it as meta, Django indeed did not understand what model you were using.
If you however do not write a form with specific items, you can - like #DanielRoseman says, just define this at the CreateView [Django-doc]:
class CreatePostView(LoginRequiredMixin,CreateView):
login_url='/login/'
redirect_field_name='Myblog/post_detail.html'
model = Post
fields = ('author', 'title', 'text')
Django can construct a form class through the modelform_factory [Django-doc].
In my model:
from django.contrib.auth.models import User
class Restaurant(models.Model):
manager = models.ForeignKey(User, on_delete=models.PROTECT,
null=True, blank=False, related_name="manager")
in my serializers.py
class RestaurantSerializer(CoreHyperlinkedModelSerializer):
class Meta:
model = Restaurant
in my views.py
class RestaurantViewSet(viewsets.ModelViewSet):
queryset = Restaurant.objects.order_by('id').all()
serializer_class = RestaurantSerializer
on my list:
the manager is displaying as <rest_framework.relations.PKOnlyObject object at 0x9f7040xbc208>
How can I display it as normal data like its username?
You want to use a 'SlugRelatedField'.
There are a few ways you can go, but if you just want to show a username, all you need is this
from rest_framework import serializers
class RestaurantSerializer(serializers.ModelSerializer):
manager = serializers.CharField(source="manager.username")
class Meta:
model = Restaurant
if you inherit from ModelSerializer and skip the manager field, it will use user PK as the value of the manager field by default.
a slightly more involved way would be to define a separate serializer for User and then embed it in RestaurantSerializer.
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
class RestaurantSerializer(serializers.ModelSerializer):
manager = UserSerializer()
class Meta:
model = Restaurant
And if you really want to use hyperlinked serializer, you need to do quite a bit of work. You need to read this part carefully http://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-determined
Before posting this question I've read few questions on SOF. but they are from 2012 and very confusing as well.
for e.g Django Rest Framework - Get related model field in serializer
my question is very straight forward
models.py
class User(models.Model):
username = models.CharField(max_length=100,unique=True)
password = models.CharField(max_length=100,null=False,blank=False)
class Car(models.Model):
user = models.ForeignKey(User)
car_name = models.CharField(max_length=100,null=True,blank=True)
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username','password' )
class CarSerializer(serializers.ModelSerializer):
#user = ?? what should I write or is there any better approach for serializing Car objects
class Meta:
model = Car
fields = ('user','car_name')
views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class CarViewSet(viewsets.ModelViewSet):
queryset = Car.objects.all()
serializer_class = CarSerializer
Please suggest all possible approaches.
1 more query. which one is better ModelSerializer or HyperlinkModelSerializer. as I saw different different answers containing these two.
You just need to do:
class CarSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Car
fields = ('user','car_name')
that is all.
Also, you should take a look to the kindnesses of serializers.Field and serializers.SerializerMethodField, you can play with them and customize your response data as much as you wish.
As to the question around HyperlinkedModelSerializer-ModelSerializer, very clear here:
The HyperlinkedModelSerializer has the following differences from ModelSerializer:
It does not include the pk field by default.
It includes a url field, using HyperlinkedIdentityField.
Relationships use HyperlinkedRelatedField, instead of PrimaryKeyRelatedField.
Hope that helps.
I cant find a way to auto-populate the field owner of my model.I am using the DRF .If i use ForeignKey the user can choose the owner from a drop down box , but there is no point in that.PLZ HELP i cant make it work.The views.py is not include cause i think there is nothing to do with it.
models.py
class Note(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
cr_date = models.DateTimeField(auto_now_add=True)
owner = models.CharField(max_length=100)
# also tried:
# owner = models.ForeignKey(User, related_name='entries')
class Meta:
ordering = ('-cr_date',)
def __unicode__(self):
return self.title
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', "username", 'first_name', 'last_name', )
class NoteSerializer(serializers.ModelSerializer):
owner = request.user.id <--- wrong , but is what a need.
# also tried :
# owner = UserSerializer(required=True)
class Meta:
model = Note
fields = ('title', 'body' )
Django Rest Framework provides a pre_save() method (in generic views & mixins) which you can override.
class NoteSerializer(serializers.ModelSerializer):
owner = serializers.Field(source='owner.username') # Make sure owner is associated with the User model in your models.py
Then something like this in your view class:
def pre_save(self, obj):
obj.owner = self.request.user
REFERENCES
http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions#associating-snippets-with-users
https://github.com/tomchristie/django-rest-framework/issues/409#issuecomment-10428031
I have an application that makes use of Django's UserProfile to extend the built-in Django User model. Looks a bit like:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
# Local Stuff
image_url_s = models.CharField(max_length=128, blank=True)
image_url_m = models.CharField(max_length=128, blank=True)
# Admin
class Admin: pass
I have added a new class to my model:
class Team(models.Model):
name = models.CharField(max_length=128)
manager = models.ForeignKey(User, related_name='manager')
members = models.ManyToManyField(User, blank=True)
And it is registered into the Admin:
class TeamAdmin(admin.ModelAdmin):
list_display = ('name', 'manager')
admin.site.register(Team, TeamAdmin)
Alas, in the admin inteface, when I go to select a manager from the drop-down box, or set team members via the multi-select field, they are ordered by the User numeric ID. For the life of me, I can not figure out how to get these sorted.
I have a similar class with:
class Meta:
ordering = ['name']
That works great! But I don't "own" the User class, and when I try this trick in UserAdmin:
class Meta:
ordering = ['username']
I get:
django.core.management.base.CommandError: One or more models did not validate:
events.userprofile: "ordering" refers to "username", a field that doesn't exist.
user.username doesn't work either. I could specify, like image_url_s if I wanted to . . . how can I tell the admin to sort my lists of users by username? Thanks!
This
class Meta:
ordering = ['username']
should be
ordering = ['user__username']
if it's in your UserProfile admin class. That'll stop the exception, but I don't think it helps you.
Ordering the User model as you describe is quite tricky, but see http://code.djangoproject.com/ticket/6089#comment:8 for a solution.
One way would be to define a custom form to use for your Team model in the admin, and override the manager field to use a queryset with the correct ordering:
from django import forms
class TeamForm(forms.ModelForm):
manager = forms.ModelChoiceField(queryset=User.objects.order_by('username'))
class Meta:
model = Team
class TeamAdmin(admin.ModelAdmin):
list_display = ('name', 'manager')
form = TeamForm
This might be dangerous for some reason, but this can be done in one line in your project's models.py file:
User._meta.ordering=["username"]
For me, the only working solution was to use Proxy Model. As stated in the documentation, you can create own proxy models for even built-in models and customize anything like in regular models:
class OrderedUser(User):
class Meta:
proxy = True
ordering = ["username"]
def __str__(self):
return '%s %s' % (self.first_name, self.last_name)
After that, in your model just change Foreign Key to:
user = models.OneToOneField(OrderedUser, unique=True)
or even more suitable
user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)