Django覆盖内联格式保存 [英] Django overriding Save on inline formset

查看:223
本文介绍了Django覆盖内联格式保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在已经僵尸了,正在等待有人打我,让我睡觉。我知道这很简单,因为我刚刚到django和python我做错了。



我想要一个模型FK字段作为文本字段呈现。我们不这么认为...


$ b $好吧,我有一个解决方案,在<反向外键关系



但唉,这对我来说没有效果,我试过,试图呃...等等..



我将我的代码放在这里,如果有人为了所有这些都是圣洁或邪恶的,可以帮助我,另外如果可能的话提供一些文档,以便我可以学习今后如何做这些事情(也教我如何捕鱼)...我会非常感激,主将淋浴他/她的祝福。



models.py

  class Recipe(models.Model): 
'''添加/更新食谱。用户和访客可以更新配方。
需要管理员批准发布食谱,除非用户是
有一些权限。 '''
user = models.ForeignKey(settings.AUTH_USER_MODEL,null = True,blank = True)
title = models.CharField(max_length = 50,verbose_name = _('Recipe | title'))
summary = models.CharField(max_length = 500,blank = True,verbose_name = _('Recipe | summary'))
description = models.TextField(blank = True,verbose_name = _描述'))
slug = models.SlugField(unique = True,max_length = 50,null = False,blank = False)
prep_time = models.CharField(max_length = 100,blank = True)字段类型是一个猜测。
ctime = models.DateTimeField(auto_now_add = True)
mtime = models.DateTimeField(auto_now = True)
sources = models.ManyToManyField(Source,blank = True)
category = models.ForeignKey(Category)
serving_string = models.ForeignKey(ServingString,null = True,blank = True)
serving_value = models.IntegerField(null = True,blank = True)
DIFFICULTY =选择((0,'easy','Easy'),(1,'medium','Medium'),(3,'hard','Hard'))
difficulty = models.IntegerField(choices = DIFFICULTY)
tag = TaggableManager(help_text =逗号分隔的标签列表)

class Ingredient(models.Model):
amount = models.FloatField(null = True ,blank = True,verbose_name = _('Ingredient | amount'))
amountMax = models.FloatField(null = True,blank = True)
unit = models.ForeignKey(Unit,null = blank = True)
食谱= models.ForeignKey(食谱)
food = models.ForeignKey(Food)
prep_method = models.ForeignKey(PrepMethod,null = True,blank = True)
order_index = PositionField(blank = True,null = True,unique_for_field =direction)
direction = models.ForeignKey(Direction,related_name ='ingredients',null = True,blank = True


class食物(models.Model):
name = models.CharField(max_length = 150,verbose_name = _ ('Food | name'))
name_sorted = models.CharField(max_length = 150,default ='',verbose_name = _('Food | name_sorted'))
group = models.ForeignKey(FoodGroup, null = True,blank = True)
conversion_src_unit = models.ForeignKey(Unit,related_name ='+',null = True,blank = True)
conversion_factor = models.FloatField(null = True,blank =
name_plural = models.CharField(max_length = 150,null = True,blank = True)
detail = models.TextField(blank = True)
in_foodguide = models.BooleanField(default =真的)

forms.py

  cl屁股RecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['title','summary','description','prep_time','sources',
'category','serve_string','serving_value','难度','标签']

class DirectionForm(forms.ModelForm):
class Meta:
model = Direction
fields = ['text',]


class FoodForm(forms.ModelForm):
class Meta:
model = Food
exclude = ['name','name_sorted','group','conversion_src_unit',
'conversion_factor','name_plural','detail','in_foodguide']

class IngredientForm(forms.ModelForm):
food_name = forms.CharField(required = True)
class Meta:
model = Ingredient
#fields = ['amount','amountMax ','unit','prep_method','food_name']
e

def __init __(self,* args,** kwargs):
super(IngredientForm,self).__ init __(* args,** kwargs)
print'instance',self.instance
如果self.instance而不是self.data:
try:
self.initial ['food_name'] = self.instance.food。 name
#我添加了try块,否则相关ObjectDOesNotExist发生错误。
#成分没有食物
除了:
通过

def save(self,commit = True):
food_name = self.cleaned_data ['food_name ']
name,_ = Food.objects.get_or_create(name = food_name)
#我打印了self.save,进入无限循环。
instance = self.save(commit = False)
instance.name = name
如果commit == True:
instance.save()
return instance

forms.py - 定义的内联表单

  DirInline = inlineformset_factory(Recipe,Direction,form = DirectionForm,extra = 1)
IngInline = inlineformset_factory(Recipe,Ingredient,form = IngredientForm,extra = 1 )

views.py

  def submit_recipe(request):
recipe_form = RecipeForm()
dir_formset = DirInline(instance = Recipe())
ing_formset = IngInline (instance = Recipe())
如果request.method =='POST':
recipe_form = RecipeForm(request.POST或None)
如果recipe_form.is_valid():
recipe = recipe_form.save(commit = False)
dir_formset = DirInline(request.POST或None,request.FILES,inst ance = recipe)
ing_formset = IngInline(request.POST或None,request.FILES,instance = recipe)
如果dir_formset.is_valid()和ing_formset.is_valid():
recipe.save ()
dir_formset.save()
ing_formset.save()
return HttpResponseRedirect(reverse('submit_recipe'))
else:
返回渲染(请求,食谱-orig / submit_recipe.html',
{'recipe_form':recipe_form,
'dir_formset':dir_formset,
'ing_formset':ing_formset})


return render(request,'recipes-orig / submit_recipe.html',
{'recipe_form':recipe_form,
'dir_formset':dir_formset,
'ing_formset':ing_formset
})

如果你觉得这是冗长的代码快速消化我会做一个简单的版本

解决方案

甜土豆!我知道我在做一些愚蠢的事情,原来我应该在保存中调用超级,我不是...这里是代码...但是如果可以,请参考一些文档。



forms.py

  def save(self,commit =真的)
food_name = self.cleaned_data ['food_name']
name,_ = Food.objects.get_or_create(name = food_name)
instance = super(IngredientForm,self).save( commit = False)
instance.food = name
如果提交:
instance.save()
返回实例


I am now zombified and am waiting for someone to hit me and put me to sleep. I know this is simple and since I am new to django and to python I am doing it wrong.

I wanted a model FK field to be rendered as a text field..easy peasy (not the linux OS)....right?

I don't think so...

well, I got one solution on SO reverse foreign key relationship

but alas it did not work for me and I tried and tried and treid...and so on...

I place my code here and if anyone for sake of all that is holy or evil can help me out on this and additionally if possible provide some documentation so I can learn how to do these things by myself in future (also teach me how to catch the fish)...I would be greatly thankful and the lord will shower his/her blessing upon you.

models.py

class Recipe(models.Model):
    ''' Add/update recipes. User and Guests can update the recipes.
    Requires admin approval for posting recipes unless user is 
    has some privileges. '''
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    title = models.CharField(max_length=50, verbose_name=_('Recipe|title'))
    summary = models.CharField(max_length=500, blank=True, verbose_name=_('Recipe|summary'))
    description = models.TextField(blank=True, verbose_name=_('Recipe|description'))
    slug = models.SlugField(unique=True, max_length=50, null=False, blank=False)
    prep_time = models.CharField(max_length=100, blank=True)  # This field type is a guess.
    ctime = models.DateTimeField(auto_now_add=True)
    mtime = models.DateTimeField(auto_now=True)
    sources = models.ManyToManyField(Source, blank=True)
    category = models.ForeignKey(Category)
    serving_string = models.ForeignKey(ServingString, null=True, blank=True)
    serving_value = models.IntegerField(null=True, blank=True)
    DIFFICULTY = Choices((0, 'easy', 'Easy'), (1, 'medium', 'Medium'), (3, 'hard', 'Hard'))
    difficulty = models.IntegerField(choices=DIFFICULTY)
    tag = TaggableManager(help_text="A comma separated list of tags")

class Ingredient(models.Model):
    amount = models.FloatField(null=True, blank=True, verbose_name=_('Ingredient|amount'))
    amountMax = models.FloatField(null=True, blank=True)
    unit = models.ForeignKey(Unit, null=True, blank=True)
    recipe = models.ForeignKey(Recipe)
    food = models.ForeignKey(Food)
    prep_method = models.ForeignKey(PrepMethod, null=True, blank=True)
    order_index = PositionField(blank=True, null=True, unique_for_field="direction")
    direction = models.ForeignKey(Direction, related_name='ingredients', null=True, blank=True)


class Food(models.Model):
    name = models.CharField(max_length=150, verbose_name=_('Food|name'))
    name_sorted = models.CharField(max_length=150, default='', verbose_name=_('Food|name_sorted'))
    group = models.ForeignKey(FoodGroup, null=True, blank=True)
    conversion_src_unit = models.ForeignKey(Unit, related_name='+', null=True, blank=True)
    conversion_factor = models.FloatField(null=True, blank=True)
    name_plural = models.CharField(max_length=150, null=True, blank=True)
    detail = models.TextField(blank=True)
    in_foodguide = models.BooleanField(default=True)

forms.py

class RecipeForm(forms.ModelForm):
    class Meta:
        model = Recipe
        fields = ['title', 'summary', 'description', 'prep_time', 'sources',
                 'category','serving_string', 'serving_value','difficulty', 'tag']

class DirectionForm(forms.ModelForm):
    class Meta:
        model = Direction
        fields = ['text', ]


class FoodForm(forms.ModelForm):
    class Meta:
        model = Food
        exclude = ['name', 'name_sorted', 'group', 'conversion_src_unit', 
                    'conversion_factor', 'name_plural', 'detail', 'in_foodguide']

class IngredientForm(forms.ModelForm):
    food_name = forms.CharField(required=True)
    class Meta:
        model =  Ingredient
        # fields = ['amount', 'amountMax', 'unit', 'prep_method', 'food_name']
        exclude = ('food',)

    def __init__(self, *args, **kwargs):
        super(IngredientForm, self).__init__(*args, **kwargs)
        print 'instance', self.instance
        if self.instance and not self.data:
            try:
                self.initial['food_name'] = self.instance.food.name
                # I added the try block else it RelatedObjectDOesNotExist Error occured.
                # Ingredient has no food
            except:
                pass

    def save(self, commit=True):
        food_name =  self.cleaned_data['food_name']
        name, _ = Food.objects.get_or_create(name=food_name)
                # I printed self.save and it goes into infinite loop.
        instance = self.save(commit=False)
        instance.name = name
        if commit == True:
            instance.save()
        return instance

forms.py - defined inline formset

DirInline = inlineformset_factory(Recipe, Direction, form=DirectionForm, extra=1)
IngInline = inlineformset_factory(Recipe, Ingredient, form=IngredientForm, extra=1)

views.py

def submit_recipe(request):
    recipe_form = RecipeForm()
    dir_formset = DirInline(instance=Recipe())
    ing_formset = IngInline(instance=Recipe())
    if request.method == 'POST':
        recipe_form = RecipeForm(request.POST or None)
        if recipe_form.is_valid():
            recipe = recipe_form.save(commit=False)
            dir_formset = DirInline(request.POST or None, request.FILES, instance=recipe)
            ing_formset = IngInline(request.POST or None, request.FILES, instance=recipe)
            if dir_formset.is_valid() and ing_formset.is_valid():
                recipe.save()
                dir_formset.save()
                ing_formset.save()
                return HttpResponseRedirect(reverse('submit_recipe'))
            else:
                return render(request, 'recipes-orig/submit_recipe.html', 
                                        {'recipe_form':recipe_form,
                                          'dir_formset':dir_formset,
                                          'ing_formset':ing_formset})


    return render(request, 'recipes-orig/submit_recipe.html', 
                                        {'recipe_form':recipe_form,
                                          'dir_formset':dir_formset,
                                          'ing_formset':ing_formset
                                        })

if you feel it is lengthy code to digest quickly I will make a simple version

解决方案

Sweet Potatoes!! I knew I was doing something dumb..it turns out I should have called super in save which I was not...here is the code...but please refer me to some documentation if you can.

forms.py

def save(self, commit=True):
    food_name =  self.cleaned_data['food_name']
    name, _ = Food.objects.get_or_create(name=food_name)
    instance = super(IngredientForm, self).save(commit=False)
    instance.food = name
    if commit:
        instance.save()
    return instance 

这篇关于Django覆盖内联格式保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆