Django How to show a customized admin model - python

Hi I want to show a customized admin model in the admin section of Django
So far I created a test_data class like this
class TestData:
#classmethod
def get_test_data(self):
list = []
for x in range(0,50):
list.append(x)
return list
and I import it on to the admin.py
from django.contrib import admin
from polls.test_data import TestData
class TestClass(admin.ModelAdmin):
list = TestData.get_test_data()
admin. site.register(TestClass)
and this gives me an error
TypeError: 'MediaDefiningClass' object is not iterable
How to fix this and show custom model in admin ? Thank you in advance

You can't pass a ModelAdmin object as the first argument to admin.site.register()
try
admin.site.register(TestData, TestClass)
You'll also need to tell your TestClass what model it refers to. more info here.

Related

Why using validators=[URLValidator] when defining a model CharField doesn't make it check for URL-validity upon saving the corresponding ModelForm?

app.models.py:
from django.core.validators import URLValidator
from django.db import models
class Snapshot(models.Model):
url = models.CharField(max_length=1999, validators=[URLValidator])
app.forms.py:
from django import forms
from .models import Snapshot
class SnapshotForm(forms.ModelForm):
class Meta:
model = Snapshot
fields = ('url',)
app.views.py:
from django.http import HttpResponse
from .forms import SnapshotForm
def index(request):
snapshot_form = SnapshotForm(data={'url': 'not an URL!'})
if snapshot_form.is_valid():
snapshot_form.save()
return HttpResponse("")
Why does it save 'not an URL!' into DB, despite the fact that it ain't a valid URL?!
What is the right way to incorporate URLValidator?
You've specified the validators for your field like so: validators=[URLValidator]. This is incorrect because the validators argument takes in a list of callables that perform the validation. In this case even though URLValidator is callable but that's actually the __init__ method of the class being called. You need to pass an instance of the class for it to work properly:
# Note the brackets after URLValidator to instantiate the class
url = models.CharField(max_length=1999, validators=[URLValidator()])
Better yet since you want to take input a URL you should simply use the URLField class for your field:
url = models.URLField(max_length=1999)

How to iterate through classes of file in python?

I have a file called models with few classes and I need to iterate throw them in order to get each class to preform the same task on it.
my problem:
from django.contrib import admin
from . import models
# this is very repetetive
admin.site.register(models.Myclass)
admin.site.register(models.MySecondclass)
admin.site.register(models.MyThirdclass)
#.
#.
#...
my goal:
from django.contrib import admin
from . import models
for class in models:
admin.site.register(class)
If you can't understand django
# models.py
import example
class Component():
return example.Component
class Post():
return "Post"
class Comment():
return "Comment"
# the goal file
from . import models
# i need to get my models as list [Component,Post,Comment]
Using inspect.getmembers with passing inspect.isclass as its second argument for predicate will give classes. To further filter to prevent other classes imported from somewhere else, ensure __module__ is "models":
import inspect
classes = [obj
for _, obj in inspect.getmembers(models, predicate=inspect.isclass)
if obj.__module__ == "models"]
gives classes as
[models.Component, models.Post, models.Comment]
after which you can do your for:
for class_ in classes:
admin.site.register(class_)
(using class_ to not override class of Python).

How to add link fields to serializer dynamically

I would like to create a general serializer for a ManyToMany link, which will include linked models data.
from rest_framework import serializers
def get_model_serializer(model, fields_to_serialize):
class BaseSerializer(serializers.ModelSerializer):
class Meta:
model = model
fields = fields_to_serialize
return BaseSerializer
def get_many_to_many_serializer(many_to_many_model, first_model, second_model, fields_to_serialize)
serializer = get_model_serializer(many_to_many_model, fields_to_serialize)
class BaseSerializer(serializer):
pass
# only when I directly set the attributes upon class definition it works
#attendee = get_model_serializer(first_model)()
#operation = get_model_serializer(second_model)()
# This does not work
setattr(BaseSerializer, first_model.__name__.lower(), get_model_serializer(first_model)())
setattr(BaseSerializer, second_model.__name__.lower(), get_model_serializer(second_model)())
#Or this
#setattr(BaseSerializer, 'operation', get_model_serializer(first_model)())
#setattr(BaseSerializer, 'attendee', get_model_serializer(second_model)())
return BaseSerializer
The problem is, that when I set the attribute using setattr, the linked models are not serialized. I guess there is some magic upon class creation or whatever?
Any ideas, how can I go around this?
You can use the three argument form of type to dynamically create new types/classes
type('M2MSerializer', (serializer, ), {
first_model.__name__.lower(): get_model_serializer(first_model)(),
first_model.__name__.lower(): get_model_serializer(first_model)()
})

FormFields for (Admin)Inlines || Can't import InlineModelAdmin

I want to catch up some extra information within my Django Admin through some extra Fields. I want to use inlines for that purpose.
I have:
class YourModelForm(forms.ModelForm):
slot_count_request = forms.IntegerField(label='#-slot-size', initial=4 )
class Card_Group_proxy_inline(admin.TabularInline):
model = SomeRandomModel
form = YourModelForm
This works fine for if I want to use a model within. I thought I can get rid of it, if I inherit from admin.InlineModelAdmin, but then I get an error:
AttributeError: module 'django.contrib.admin' has no attribute 'InlineModelAdmin'
The InlineModelAdmin class can be imported with:
from django.contrib.admin.options import InlineModelAdmin
However, I have not seen InlineModelAdmin used directly before. Usually, you would use admin.TabularInline or admin.StackedInline.

Django add field to existing model app

in my new Django app I use 3rd-part Photologue app.
This app works well, but I need to add some field in its model without change the original source code of Photologue app.
With this snippet, all works well, but maybe this is not the best solution:
Photo.add_to_class("link", models.URLField(max_leng.... ))
I've read some posts where I should use OneToOneRelationField ... but then, in django admin app, I will have two different form page of Photo and new PhotoLink class...
Does anyone can help me?
If you are using a OneToOneField, you can use your 'extension' model as an inline to the model you are extending. You do this by first un-registering the original admin class, and then overriding it with our variant:
from otherapp.admin import OriginalFooAdmin
from otherapp.models import Foo
from yourapp.models import YourExtension
from django.contrib import admin
admin.site.unregister(Foo)
class ExtensionInline(admin.StackedInline):
model = YourExtension
class NewFooAdmin(OriginalFooAdmin):
inlines = OriginalFooAdmin.inlines + [ExtensionInline]
admin.site.register(Foo, NewFooAdmin)

Categories