14

Tôi đang cố truy cập ForeignKeys trong Chế độ xem Lớp học CreateView. Tôi muốn có thể tự động thiết lập giá trị ban đầu trong CBV từ ForeignKeys và cũng tự động thiết lập các liên kết mẫu từ ForeignKeys.đặt giá trị ban đầu trong CreateView từ ForeignKey (non-self.request.user)

Hai câu hỏi này (1. giá trị ban đầu, 2. liên kết mẫu) có thể được giải quyết theo các phương pháp tương tự, hoặc có thể bằng các phương pháp khác nhau ... Tôi vẫn đang học. Có lẽ câu hỏi đầu tiên có thể được giải quyết trong vòng views.py và câu hỏi thứ hai có thể được giải quyết với cú pháp mẫu trong ingredient_form.html?

Tôi đã nhìn thấy các câu hỏi về SO đặt giá trị ban đầu từ người dùng (self.request.user), nhưng không chỉ từ khóa ngoại bình thường trong models.py.

Tôi sẽ thông qua django-by-errors và cố gắng thêm các tính năng bổ sung để mở rộng kiến ​​thức django của tôi.

Câu hỏi của tôi đặc biệt tập trung vào views.py:IngredientAddView(CreateView), trên ingredient_form.html, và trên urls.py:'recipe-detail' & 'ingredient-add'.

Khi tôi xem 'recipe-detail', tôi có thể nhấp vào liên kết đến 'ingredient-add'. Tôi muốn 'ingredient-add' để "biết" công thức nào được nhấp vào nó và có thể đặt công thức này làm giá trị ban đầu (nỗ lực của tôi trong phạm vi views.py:IngredientAddView:get_initials(self) không hoạt động) và cũng có thể liên kết lại công thức này (nỗ lực của tôi trong phạm vi ingredient_form.html:{% comment %} không hoạt động).

Sẽ đánh giá cao mọi trợ giúp.

models.py

class Food(models.Model): 
    name=models.CharField(max_length=20,unique=True) 

    def __str__(self): 
     return self.name 

    def get_absolute_url(self): 
     return reverse('food-detail',kwargs={'pk':self.pk}) 

class Recipe(models.Model): 
    title=models.CharField(max_length=80,unique=True) 
    slug=models.SlugField(max_length=80,unique=True) 
    description=models.TextField(blank=True) 

    def __str__(self): 
     return self.title 

    def get_absolute_url(self): 
     return reverse('recipe-detail',kwargs={'slug':self.slug}) 

class Ingredient(models.Model): 
    recipe=models.ForeignKey(Recipe) 
    food=models.ForeignKey(Food) 

    def __str__(self): 
     return '%s (%s)' % (self.food, self.recipe) 

views.py

class FoodListView(ListView): 
    model=Food 

class FoodDetailView(DetailView): 
    model=Food 

class FoodCreateView(CreateView): 
    model=Food 

class RecipeListView(ListView): 
    model=Recipe 

class RecipeDetailView(DetailView): 
    model=Recipe 

class RecipeCreateView(CreateView): 
    model=Recipe 

class RecipeUpdateView(UpdateView): 
    model=Recipe 

class IngredientAddView(CreateView): 
    model=Ingredient 

# def get_context_data(self,**kwargs): 
#  context=super(IngredientAddView,self).get_context_data(**kwargs) 
#  context['foreign']=self.request.session.get('slug') 

    def get_initials(self): 
     return { 
      'recipe':self.request.session.get('recipe') 
     } 

urls.py

from .views import FoodListView, FoodDetailView, FoodCreateView, RecipeListView, RecipeDetailView, RecipeCreateView, RecipeUpdateView, IngredientAddView 

urlpatterns=patterns('', 
        url(r'^$',RecipeListView.as_view(),name='recipe-list'), 
        url(r'^(?P<slug>[-\w]+)$',RecipeDetailView.as_view(),name='recipe-detail'), 
        url(r'^(?P<slug>[-\w]+)/edit$',RecipeUpdateView.as_view(),name='recipe-edit'), 
        url(r'^(?P<slug>[-\w]+)/add_ingredient/$',IngredientAddView.as_view(),name='ingredient-add'), 
        url(r'^new/$',RecipeCreateView.as_view(),name='recipe-create'), 
        url(r'^food/$',FoodListView.as_view(),name='food-list'), 
        url(r'^food/(?P<pk>[\d]+)$',FoodDetailView.as_view(),name='food-detail'), 
        url(r'^food/create/$',FoodCreateView.as_view(),name='food-create'), 
       ) 

recipe_detail.html

{% extends "base_food.html" %} 

{% block title %}{{ recipe }} {% endblock %} 

{% block content %} 
    <h1>{{ recipe }}</h1> 
    <p>{{ recipe.id }}</p> 
    <p>{{ recipe.title }}</p> 

    <br> 
    <h2>Description</h2> 
    <p>{{ recipe.description|default:'No description' }}</p> 

    <h2>Ingredients</h2> 
    <ul> 
    {% for ingredient in recipe.ingredient_set.all %} 
     <li>{{ ingredient }}</li> 
    {% endfor %} 
    </ul> 
    <p><a href="{% url 'ingredient-add' recipe.slug %}">Add ingredient</a></p> 
    <p><a href="{% url 'recipe-edit' recipe.slug %}">Edit recipe</a></p> 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 

ingredient_form.html

{% extends "base_food.html" %} 

{% block title %}Add Ingredient{% endblock %} 

{% block content %} 
    <h1>Add Ingredient</h1> 
    <form method="POST">{% csrf_token %} 
    {{ form }} 
    <button type="submit" class="btn btn-primary">Save</button> 
    </form> 

{%comment%} <p><a href="{% url 'recipe-detail' recipe.slug %}">Back to detail</a></p> {%endcomment%} 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 
+0

Tôi nghĩ rằng cách dễ dàng để làm những gì bạn đang yêu cầu là phải có một url với pk của 'recipe-chi tiết 'trong đó. Một cái gì đó như '/ your_url/13'. Sau đó, khung nhìn có thể sử dụng pk đó để chỉ định cá thể FK cụ thể. –

+0

Tôi đồng ý sử dụng pk cho url dễ dàng hơn - nhưng tôi hình dung một ứng dụng web thân thiện với người dùng khi sử dụng các url có ý nghĩa. Tôi cũng muốn mở rộng kiến ​​thức của tôi về django. – Jeremiah

Trả lời

20

Bạn cần phải nhanh chóng công thức của bạn:

class IngredientAddView(CreateView): 
    model=Ingredient 

    def get_initial(self): 
     recipe = get_object_or_404(Recipe, slug=self.kwargs.get('slug')) 
     return { 
      'recipe':recipe, 
     } 
+1

Bingo. Điều này làm việc. Cảm ơn bạn. Để tham khảo trong tương lai, hàm thực sự là 'get_initial (self)' nhưng đó là lỗi của tôi đối với lỗi đánh máy ban đầu. – Jeremiah

+0

Bạn đã đúng, tôi đã sửa câu trả lời. Tôi cũng đang viết ra khỏi đầu. :-) –

Các vấn đề liên quan