I have a model (as below) and in that, I've set auto_now_add=True for the DateTimeField
class Foo(models.Model):
timestamp = models.DateTimeField(auto_now_add=True)
From the doc,
As currently implemented, setting auto_now or auto_now_add to True will cause the field to have editable=False and blank=True set.
Q: How Can I show this auto_now_add field in Django Admin? (by default Django Admin doesn't show auto_now_add fields)
We can forcefully show the auto_now_add=True fields by adding the particular field(s) to the readonly_fields - (Django doc) list
class FooAdmin(admin.ModelAdmin):
readonly_fields = ('timestamp',)
admin.site.register(Foo, FooAdmin)
Related
I have two models, here is simplified example of it:
class Application(TimestampedModel):
...
forms = models.ManyToManyField(Form, related_name='applications', through='ApplicationForm', blank=True)
class ApplicationForm(models.Model):
application = models.ForeignKey(Application, on_delete=models.CASCADE)
form = models.ForeignKey(Form, on_delete=models.CASCADE)
created_at = models.DateTimeField()
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
I want to filter forms field on Application model. I try to do this:
queryset = Application.objects.get_active().filter(is_public=True, pk=self.kwargs['pk'])
for application in queryset:
forms = application.forms.filter(form_sections__form_fields__pk__in=application.public_form_fields.all())
application.forms.set(forms)
But I get an error:
AttributeError at /api/applications/public/79
Cannot set values on a ManyToManyField which specifies an intermediary model. Use applications.ApplicationForm's Manager instead.
So my question is it possible, and if possible how can I do this?
You're using an intermediary model, you should read this. You can only use set() if you provide defaults for the extra fields (in your case created_at). Otherwise, you have to create the ApplicationForm objects yourself.
So this would probably work in Django 2.2:
application.forms.set(forms, through_defaults={'created_at': timezone.now()})
In earlier versions of Django you have to go through the intermediate model:
application.forms.clear() # remove all existing relations
for form in forms:
ApplicationForm.objects.create(application=application, form=form, created_at=timezone.now())
I use the default User class from from django.contrib.auth.models import User. In the user creation when the user is created I set the username field to a random hash. When I use the model in ManyToMany field and use it in the Django admin then the random hash is rendered in the select box. Is there a way to specify the field to be taken from the model to be displayed in the select box so that I can specify the model as ManyToMany field and use the email to be rendered in the django admin form.
class TestModel(models.Model):
group = models.ManyToManyField(Group, null=True)
user = models.ManyToManyField(User, null=True)
Is there a field like the display_name that can be passed to the model field so that the appropriate field can be taken from the ManyToMany model for rendering. I am using Django 1.5.5
I think you need to do something like this,
class TestModelAdminForm(forms.ModelForm):
user = forms.MultipleChoiceField(choices=[ (user.id, user.email) for user in User.objects.all()])
class Meta:
model = TestModel
fields = ('user','group')
class TestModelAdmin(admin.ModelAdmin):
form = TestModelAdminForm
This is my Model:
class Post(models.Model):
user = models.ForeignKey(User)
post = models.CharField(max_length=400)
country = models.ForeignKey(Country, blank=True, null=True)
and this is my serializer:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('user', 'post', 'country',)
def create(self, validated_data):
post = Post(
user = User.objects.get(username='MyUser'),
post = validated_data['post'],
)
if validated_data.get('country', None):
post.country = validated_data['country']
return post
Is there any way for me to tell DRF that if the value of the field is null (because the 'country' field is optional and sometimes not provided) then to skip it and just serialize the other data? Or at least serialize it with a value of None?
I don't think I can use SerializerMethodField (http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield) because the 'country' field is not a read-only field (I write too it too, if it is provided).
I basically want to omit the field (or at least make the value None) when serializing an object If the field is null.
As of DRF 3.2.4, so long as you add
blank=True
to the models field like so:
class Post(models.Model):
country = models.ForeignKey(Country, blank=True)
then DRF will treat the field as optional when serializing and deserializing it (Note though that if there is no null=True on the model field, then Django will raise an error if you try to save an object to the database without providing the field).
See the answer here for more information: DjangoRestFramework - correct way to add "required = false" to a ModelSerializer field?
If you are using pre-DRF 3.2.4, then you can override the field in the serializer and add required=False to it. See the documentation here for more information on specifying or overriding fields explicitily: http://www.django-rest-framework.org/api-guide/serializers/#specifying-fields-explicitly
So something like this (Note that I did not fully test the code below but it should be something along these lines):
class PostSerializer(serializers.ModelSerializer):
country = serializers.PrimaryKeyRelatedField(required=False)
class Meta:
model = Post
fields = ('user', 'post', 'country',)
This thread might be useful:
https://stackoverflow.com/a/28870066/4698253
It basically says that you can override the to_representation() function with a slight modification.
I would have put this in the comments but I don't have enough points yet :(
Use allow_null=True:
allow_null - If set to True, the field will accept values of None or the empty string for nullable relationships. Defaults to False.
serializers.py
class PostSerializer(serializers.ModelSerializer):
tracks = serializers.PrimaryKeyRelatedField(allow_blank=True)
class Meta:
model = Post
I'm writing a model called talk that has two fields title and slug. slug is a field which I do not wish the user to be able to edit and is pre-populated based on title. The model looks like this:
class talk(models.Model):
title = models.CharField(max_length = 255)
slug = models.SlugField(editable=False)
In my admin.py I have the following:
class talkAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
Trying to access the model in the CMS gives me the error Exception Value: u"Key 'slug' not found in Form". If I remove editable=False everything works as desired except the user can edit the slug as they see fit.
I would like the slug field to appear in the admin but be greyed out so the user can see the slug, but can not change it.
You should use readonly_fields in the ModelAdmin class, not editable in the model.
I have the following django model:
class Article(models.Model):
title = models.CharField(max_length = 200)
body = models.TextField()
created_date = models.DateTimeField(auto_now_add=True)
I also have the following django admin class:
class ArticleAdmin(admin.ModelAdmin):
fields = ['title', 'body']
readonly_fields = ['created_date']
list_display = ['title', 'body', 'created_date']
In the django admin app I can see the created_date field in my Article list:
But for the life of me I can't get the created_date field to render (as a read only field) when I open an Article:
I got the impression from the docs and from googling around that adding Article's created_date field to readonly_fields would allow this to happen even if I had set auto_now_add to True on a DateTimeField.
Am I barking up the wrong tree here?
I'm using django 1.4.2.
If you've specified fields, you need to add the field to fields.
however, when you specify ModelAdmin.fields or ModelAdmin.fieldsets the read-only fields must be present to be shown (they are ignored otherwise).
The auto_now magic has gotten me a few times.