【问题标题】:How to get values from one model to appear in another in Django如何从一个模型中获取值以出现在 Django 中的另一个模型中
【发布时间】:2018-06-24 00:13:59
【问题描述】:

我是 Django 新手,所以请善待 -_^。

我有两个模型“猫”和“窝”。

垃圾包含两个具有名称的元素。

我有一群猫。

我希望作为用户,我可以根据猫砂模型中存在的猫砂名称将任何猫与猫砂相关联。

我该如何做到这一点?

(我尝试过“一对多”、“多对多”和“反向关系”……我是 DJANGO 的新手,所以我不声称这些尝试中的任何一个都做得正确。

这是我当前的models.py

...
class Litter(models.Model):
    name = models.CharField(max_length=255)
    notes = models.CharField(max_length=2048, blank=True, null=True)

    created = models.DateTimeField(blank=True, null=True)
    modified = models.DateTimeField(blank=True, null=True)

    def save(self, *args, **kwargs):
        # Save time Litter object modified and created times
        self.modified = datetime.datetime.now()
        if not self.created:
            self.created = datetime.datetime.now()

        super(Litter, self).save(*args, **kwargs)

    def __str__(self):
        return self.name


class Cat(models.Model):
    litter_mates = models.ManyToManyField(Litter)

    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female')
    )
    MALE = 'M'
    FEMALE = 'F'

    CAT_TYPE = (
        ('O','Orphan'),
        ('P','Pregnant'),
        ('N','Nursing')
    )
    Orphan = 'O'
    Pregnant = 'P'
    Nursing = 'N'

    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, blank=True, null=True)

    reference_id = models.CharField(max_length=255, blank=True, null=True)
    short_name = models.SlugField(max_length=255, blank=True, null=True,
                                  help_text="This name is auto generated from the name and reference ID. "
                                            "It is used to make it easy to find the animal in a URL lookup.")

    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default=MALE)
    cat_type = models.CharField(max_length=1, choices=CAT_TYPE, default=Orphan)
    color = models.CharField(max_length=255, blank=True, null=True)
    weight_unit = models.CharField(max_length=2, choices=Weight.MEASURE_CHOICES, default=Weight.GRAMS)
    weight = models.IntegerField(blank=True, null=True)
    notes = models.TextField(blank=True, null=True)
    birthday = models.DateTimeField(blank=True, null=True)
    photo = models.FileField(upload_to="kitty_photos", blank=True, null=True)
    created = models.DateTimeField(blank=True, null=True)
    modified = models.DateTimeField(blank=True, null=True)

    alert_feeder = models.BooleanField(default=False,
                                       help_text='Alert feeder to critical situations')
    critical_notes = models.TextField(blank=True, null=True)

    first_weight_loss = models.BooleanField(default=False)
    second_weight_loss = models.BooleanField(default=False)
    third_weight_loss = models.BooleanField(default=False)
    many_weight_losses = models.BooleanField(default=False)

    def save(self, *args, **kwargs):

        # Check to see if slug exists, if it does, make a counter
        self.slug = orig = slugify(self.name)

        for x in itertools.count(1):
            if not Cat.objects.filter(slug=self.slug).exists():
                break
            self.slug = '%s-%d' % (orig, x)

        self.modified = datetime.datetime.now()
        if not self.created:
            self.created = datetime.datetime.now()
        self.short_name = slugify("{name}-{reference_id}".format(name=self.name, reference_id=self.reference_id))

        super(Cat, self).save(*args, **kwargs)

    @models.permalink
    def get_absolute_url(self):
        return 'tracker:cat', (self.slug,)

    def __str__(self):
        return self.name

...

这是我的 serializers.py

...
class LitterSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Litter
        fields = (
            'id',
            'name',
            'notes'
        )


class CatSerializer(serializers.HyperlinkedModelSerializer):
    litter_mates = LitterSerializer(many=True)

    class Meta:
        model = Cat
        fields = (
            'id',
            'name',
            'slug',
            'reference_id',
            'short_name',
            'gender',
            'cat_type',
            'litter_mates',
            'color',
            'weight_unit',
            'weight',
            'notes',
            'birthday',
            'photo',
            'created',
            'modified',
            'alert_feeder',
            'critical_notes',
            'first_weight_loss',
            'second_weight_loss',
            'third_weight_loss',
            'many_weight_losses'
        )

    def create(self, validated_data):
        litter_data = validated_data.pop('tracks')
        cat = Cat.objects.create(**validated_data)
        for litter_data in litter_data:
            Litter.objects.create(cat=cat, **litter_data)
        return cat


...

现在我想如果我可以在http://localhost:8000/api/v1/cats/ 获得我的管理页面,以向我展示创建/更新包含“litter_mates”下拉列表的猫表格,其中包含我的两窝的名字...我会得到什么我需要。

感谢您的关注。

更新:

这也是我的admin.py

from __future__ import unicode_literals
from django.contrib import admin
from jsoneditor.forms import JSONEditor
from django.contrib.postgres.fields import JSONField
from . import models as tracker_models
from import_export.admin import ImportExportModelAdmin
from import_export import resources


class LitterResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Litter


class MedicationResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Medication


class FeedingResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Feeding


class CatResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Cat


class LitterAdmin(ImportExportModelAdmin):
    search_fields = ['name']
    list_display = ['name', 'created', 'modified']
    resource_class = LitterResource


class MedicationAdmin(ImportExportModelAdmin):
    search_fields = ['cat__name', 'notes']
    list_display = ['cat', 'duration', 'notes', 'frequency', 'dosage', 'dosage_unit',
                    'created', 'modified']
    resource_class = MedicationResource


class FeedingInline(admin.TabularInline):
    model = tracker_models.Feeding
    extra = 1
    exclude = ['modified']
    readonly_fields = ['created']


class FeedingAdmin(ImportExportModelAdmin):
    search_fields = ['cat__name', 'amount_of_food_taken', 'notes']
    list_display = ['cat', 'weight_unit_measure', 'weight_before_food', 'food_unit_measure', 'amount_of_food_taken',
                    'food_type', 'weight_after_food', 'stimulated', 'stimulation_type', 'notes', 'photo',
                    'created', 'modified']
    resource_class = FeedingResource


class CatAdmin(ImportExportModelAdmin):
    search_fields = ['name', 'reference_id', 'short_name', 'gender', 'notes']
    list_display = ['name', 'reference_id', 'short_name', 'gender', 'weight_unit', 'weight', 'notes', 'birthday', 'photo',
                    'alert_feeder', 'critical_notes', 'first_weight_loss', 'second_weight_loss', 'third_weight_loss',
                    'many_weight_losses', 'created', 'modified']
    inlines = [
        FeedingInline
    ]
    resource_class = CatResource


__custom_admins__ = {
    'Cat': CatAdmin,
    'Feeding': FeedingAdmin,
    'Medication': MedicationAdmin,
    'Litter': LitterAdmin,
}

for model in tracker_models.__admin__:
    params = [getattr(tracker_models, model)]
    if model in __custom_admins__:
        params.append(__custom_admins__[model])
    else:
        _dyn_class = type('%sAdmin' % ( model,), (admin.ModelAdmin,), {})
        params.append(_dyn_class)
    admin.site.register(*params)

admin.site.site_title = 'KittyTracker Admin'
admin.site.site_header = 'KittyTracker Admin'

更新二:

现在当我转到“http://localhost:8000/api/v1/cats/”时,我收到以下错误...

django.db.utils.ProgrammingError

django.db.utils.ProgrammingError: column tracker_cat.litter_id does not exist
LINE 1: SELECT "tracker_cat"."id", "tracker_cat"."litter_id", "track...

【问题讨论】:

    标签: django django-forms django-rest-framework


    【解决方案1】:

    我会在您的 Cats 模型中使用多对一关系。 这将允许您将您的猫分配到一窝,一窝可以包含许多猫。

    class Cat(models.Model):
    ...
    litter = models.ForeignKey(Litter, on_delete=None)
    ...
    

    【讨论】:

    • 我已经更新了我的问题以包括我的内部 admin.py....我不清楚在该文件中注册我的 2 个类的确切位置(我是 Django 新手)
    • 只需将 2 行添加到最底部即可。
    • 当我将这两行添加到 admin.py 的最底部时,我收到一条错误消息,提示“未解决的参考...”
    • 您还必须导入模型。像这样:from .models import Cat, Litter
    • "django.contrib.admin.sites.AlreadyRegistered: 模型猫已经注册"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多