2010-07-19 17 views
6

Tôi đã đặt cùng một biểu mẫu để lưu công thức. Nó sử dụng một biểu mẫu và một formset nội tuyến. Tôi có người dùng với các tập tin văn bản có chứa công thức nấu ăn và họ muốn cắt và dán dữ liệu để làm cho mục nhập dễ dàng hơn. Tôi đã làm việc ra làm thế nào để cư các phần hình thức sau khi xử lý đầu vào văn bản thô nhưng tôi không thể tìm ra cách để điền vào formset nội tuyến.Dữ liệu ban đầu cho các hình thức nội tuyến Django

Có vẻ như giải pháp gần như được viết ở đây: http://code.djangoproject.com/ticket/12213 nhưng tôi không thể ghép các mảnh lại với nhau.

mô hình của tôi:

#models.py 

from django.db import models 

class Ingredient(models.Model): 
    title = models.CharField(max_length=100, unique=True) 

    class Meta: 
     ordering = ['title'] 

    def __unicode__(self): 
     return self.title 

    def get_absolute_url(self): 
     return self.id 

class Recipe(models.Model): 
    title = models.CharField(max_length=255) 
    description = models.TextField(blank=True) 
    directions = models.TextField() 

    class Meta: 
     ordering = ['title'] 

    def __unicode__(self): 
     return self.id 

    def get_absolute_url(self): 
     return "/recipes/%s/" % self.id 

class UnitOfMeasure(models.Model): 
    title = models.CharField(max_length=10, unique=True) 

    class Meta: 
     ordering = ['title'] 

    def __unicode__(self): 
     return self.title 

    def get_absolute_url(self): 
     return self.id 

class RecipeIngredient(models.Model): 
    quantity = models.DecimalField(max_digits=5, decimal_places=3) 
    unit_of_measure = models.ForeignKey(UnitOfMeasure) 
    ingredient = models.ForeignKey(Ingredient) 
    recipe = models.ForeignKey(Recipe) 

    def __unicode__(self): 
     return self.id 

Dạng thức được tạo ra bằng cách sử dụng ModelForm:

class AddRecipeForm(ModelForm): 
    class Meta: 
     model = Recipe 
     extra = 0 

Và mã có liên quan trong giao diện (gọi để phân tích ra các hình thức đầu vào được xóa):

def raw_text(request): 
    if request.method == 'POST': 

    ...  

     form_data = {'title': title, 
        'description': description, 
        'directions': directions, 
        } 

     form = AddRecipeForm(form_data) 

     #the count variable represents the number of RecipeIngredients 
     FormSet = inlineformset_factory(Recipe, RecipeIngredient, 
         extra=count, can_delete=False) 
     formset = FormSet() 

     return render_to_response('recipes/form_recipe.html', { 
       'form': form, 
       'formset': formset, 
       }) 

    else: 
     pass 

    return render_to_response('recipes/form_raw_text.html', {}) 

Với FormSet() trống như trên, tôi có thể khởi chạy thành công trang. Tôi đã thử một vài cách để nuôi formset số lượng, unit_of_measure và các thành phần tôi đã xác định bao gồm:

  • thiết lập dữ liệu ban đầu nhưng điều đó không làm việc cho formsets inline
  • đi qua một từ điển, nhưng điều đó tạo quản lý lỗi hình thức
  • chơi xung quanh với init nhưng tôi một chút ra khỏi sâu của tôi ở đó

Bất kỳ lời đề nghị đánh giá cao rất nhiều.

Trả lời

19

Đề xuất đầu tiên của tôi là thực hiện một cách đơn giản: lưu RecipeRecipeIngredient s, sau đó sử dụng kết quả Recipe làm ví dụ của bạn khi tạo FormSet. Bạn có thể muốn thêm trường boolean "đã xem xét" vào công thức nấu ăn của bạn để cho biết liệu các biểu mẫu đã được người dùng phê duyệt hay chưa.

Tuy nhiên, nếu bạn không muốn đi theo con đường mà vì lý do gì, bạn sẽ có thể để cư formsets của bạn như thế này:

Chúng tôi sẽ giả định rằng bạn đã phân tích các dữ liệu văn bản vào các thành phần công thức và có danh sách từ điển như thế này:

recipe_ingredients = [ 
    { 
     'ingredient': 2, 
     'quantity': 7, 
     'unit': 1 
    }, 
    { 
     'ingredient': 3, 
     'quantity': 5, 
     'unit': 2 
    }, 
] 

Số trong trường "thành phần" và "đơn vị" là giá trị khóa chính cho các thành phần và đơn vị đo lường tương ứng. Tôi cho rằng bạn đã xây dựng một số cách để kết hợp văn bản với các thành phần trong cơ sở dữ liệu của bạn hoặc tạo các văn bản mới.

Sau đó bạn có thể làm:

RecipeFormset = inlineformset_factory(
    Recipe, 
    RecipeIngredient, 
    extra=len(recipe_ingredients), 
    can_delete=False) 
formset = RecipeFormset() 

for subform, data in zip(formset.forms, recipe_ingredients): 
    subform.initial = data 

return render_to_response('recipes/form_recipe.html', { 
    'form': form, 
    'formset': formset, 
    }) 

này đặt initial tài sản của mỗi hình thức trong formset để một cuốn từ điển từ danh sách recipe_ingredients của bạn. Nó dường như làm việc cho tôi trong việc hiển thị các formset, nhưng tôi đã không cố gắng tiết kiệm được nêu ra.

+0

Lời khuyên tuyệt vời Aram, cảm ơn bạn rất nhiều. Tôi sẽ thử các tùy chọn hiện nay. Tôi đặc biệt thích có một lựa chọn dễ dàng ... – Sinidex

+0

Sử dụng zip chắc chắn hoạt động và tôi có thể xác nhận rằng lưu các hình thức trong thời trang thông thường hoạt động là tốt. Tôi vẫn cần phải xây dựng ra phù hợp với văn bản phân tích cú pháp để các thành phần có liên quan và các đơn vị của đối tượng đo như bạn chỉ ra, nhưng tôi nghĩ rằng nên được quản lý. Giải pháp tuyệt vời. – Sinidex

+1

Có có và có. Đây là một giải pháp tuyệt vời! Tôi đã có một thời gian khó khăn để đạt được điều này. Tôi đã lần đầu tiên tìm hiểu làm thế nào để xây dựng mỗi hình thức trong bộ này. Sau đó, nhận ra * ban đầu * làm việc, trên một hình thức (không formset) cơ sở. Trong zip chúng tôi tin tưởng ™ – Flowpoke

0

tôi không thể làm cho Aram Dulyan đang hoạt động trên này

for subform, data in zip(formset.forms, recipe_ingredients): 
    subform.initial = data 

Rõ ràng cái gì đó thay đổi trên django 1.8 mà tôi không thể lặp một cached_property

hình thức - django.utils.functional. đối tượng cached_property tại 0x7efda9ef9080

tôi đã nhận lỗi này

luận zip # 1 phải hỗ trợ lặp

Nhưng tôi vẫn đi theo từ điển và gán nó trực tiếp đến formset của tôi và nó làm việc, tôi lấy ví dụ từ đây:

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform

từ django.forms nhập khẩu formset_factory từ myapp.forms nhập ArticleForm

ArticleFormSet = formset_factory(ArticleForm, can_order=True) 
formset = ArticleFormSet(initial=[ 
    {'title': 'Article #1', 'pub_date': datetime.date(2008, 5, 10)}, 
    {'title': 'Article #2', 'pub_date': datetime.date(2008, 5, 11)}, 
]) 

Mã của tôi khi chỉ định biểu mẫu cho mẫu

return self.render_to_response(
self.get_context_data(form=form, inputvalue_numeric_formset=my_formset(initial=formset_dict) 
Các vấn đề liên quan